gitlab-mail_room 0.0.10 → 0.0.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitlab/issue_templates/Release.md +1 -0
- data/.gitlab-ci.yml +0 -4
- data/.rubocop.yml +5 -0
- data/.rubocop_todo.yml +501 -0
- data/.travis.yml +9 -3
- data/README.md +88 -9
- data/Rakefile +1 -1
- data/lib/mail_room/arbitration/redis.rb +1 -1
- data/lib/mail_room/connection.rb +1 -3
- data/lib/mail_room/delivery/letter_opener.rb +1 -1
- data/lib/mail_room/delivery/sidekiq.rb +4 -3
- data/lib/mail_room/mailbox.rb +56 -17
- data/lib/mail_room/mailbox_watcher.rb +7 -1
- data/lib/mail_room/microsoft_graph/connection.rb +217 -0
- data/lib/mail_room/microsoft_graph.rb +7 -0
- data/lib/mail_room/version.rb +1 -1
- data/mail_room.gemspec +6 -0
- data/spec/lib/cli_spec.rb +3 -3
- data/spec/lib/configuration_spec.rb +1 -1
- data/spec/lib/delivery/letter_opener_spec.rb +2 -2
- data/spec/lib/delivery/logger_spec.rb +1 -1
- data/spec/lib/delivery/postback_spec.rb +11 -11
- data/spec/lib/delivery/sidekiq_spec.rb +29 -7
- data/spec/lib/mailbox_spec.rb +65 -17
- data/spec/lib/mailbox_watcher_spec.rb +54 -38
- data/spec/lib/microsoft_graph/connection_spec.rb +190 -0
- data/spec/spec_helper.rb +13 -3
- metadata +64 -2
@@ -31,7 +31,7 @@ module MailRoom
|
|
31
31
|
# Any subsequent failure in the instance which gets the lock will be dealt
|
32
32
|
# with by the expiration, at which time another instance can pick up the
|
33
33
|
# message and try again.
|
34
|
-
client.set(key, 1, {:
|
34
|
+
client.set(key, 1, {nx: true, ex: expiration})
|
35
35
|
end
|
36
36
|
|
37
37
|
private
|
data/lib/mail_room/connection.rb
CHANGED
@@ -24,7 +24,7 @@ module MailRoom
|
|
24
24
|
# Trigger `LetterOpener` to deliver our message
|
25
25
|
# @param message [String] the email message as a string, RFC822 format
|
26
26
|
def deliver(message)
|
27
|
-
method = ::LetterOpener::DeliveryMethod.new(:
|
27
|
+
method = ::LetterOpener::DeliveryMethod.new(location: @delivery_options.location)
|
28
28
|
method.deliver!(Mail.read_from_string(message))
|
29
29
|
|
30
30
|
true
|
@@ -8,16 +8,17 @@ module MailRoom
|
|
8
8
|
# Sidekiq Delivery method
|
9
9
|
# @author Douwe Maan
|
10
10
|
class Sidekiq
|
11
|
-
Options = Struct.new(:redis_url, :namespace, :sentinels, :queue, :worker, :logger) do
|
11
|
+
Options = Struct.new(:redis_url, :namespace, :sentinels, :queue, :worker, :logger, :redis_db) do
|
12
12
|
def initialize(mailbox)
|
13
13
|
redis_url = mailbox.delivery_options[:redis_url] || "redis://localhost:6379"
|
14
|
+
redis_db = mailbox.delivery_options[:redis_db] || 0
|
14
15
|
namespace = mailbox.delivery_options[:namespace]
|
15
16
|
sentinels = mailbox.delivery_options[:sentinels]
|
16
17
|
queue = mailbox.delivery_options[:queue] || "default"
|
17
18
|
worker = mailbox.delivery_options[:worker]
|
18
19
|
logger = mailbox.logger
|
19
20
|
|
20
|
-
super(redis_url, namespace, sentinels, queue, worker, logger)
|
21
|
+
super(redis_url, namespace, sentinels, queue, worker, logger, redis_db)
|
21
22
|
end
|
22
23
|
end
|
23
24
|
|
@@ -45,7 +46,7 @@ module MailRoom
|
|
45
46
|
def client
|
46
47
|
@client ||= begin
|
47
48
|
sentinels = options.sentinels
|
48
|
-
redis_options = { url: options.redis_url }
|
49
|
+
redis_options = { url: options.redis_url, db: options.redis_db }
|
49
50
|
redis_options[:sentinels] = sentinels if sentinels
|
50
51
|
|
51
52
|
redis = ::Redis.new(redis_options)
|
data/lib/mail_room/mailbox.rb
CHANGED
@@ -1,11 +1,14 @@
|
|
1
1
|
require "mail_room/delivery"
|
2
2
|
require "mail_room/arbitration"
|
3
3
|
require "mail_room/imap"
|
4
|
+
require "mail_room/microsoft_graph"
|
4
5
|
|
5
6
|
module MailRoom
|
6
7
|
# Mailbox Configuration fields
|
7
8
|
MAILBOX_FIELDS = [
|
8
9
|
:email,
|
10
|
+
:inbox_method,
|
11
|
+
:inbox_options,
|
9
12
|
:password,
|
10
13
|
:host,
|
11
14
|
:port,
|
@@ -42,24 +45,26 @@ module MailRoom
|
|
42
45
|
# 29 minutes, as suggested by the spec: https://tools.ietf.org/html/rfc2177
|
43
46
|
IMAP_IDLE_TIMEOUT = 29 * 60 # 29 minutes in in seconds
|
44
47
|
|
45
|
-
|
48
|
+
IMAP_CONFIGURATION = [:name, :email, :password, :host, :port].freeze
|
49
|
+
MICROSOFT_GRAPH_CONFIGURATION = [:name, :email].freeze
|
50
|
+
MICROSOFT_GRAPH_INBOX_OPTIONS = [:tenant_id, :client_id, :client_secret].freeze
|
46
51
|
|
47
52
|
# Default attributes for the mailbox configuration
|
48
53
|
DEFAULTS = {
|
49
|
-
:
|
50
|
-
:
|
51
|
-
:
|
52
|
-
:
|
53
|
-
:
|
54
|
-
:
|
55
|
-
:
|
56
|
-
:
|
57
|
-
:
|
58
|
-
:
|
59
|
-
:
|
60
|
-
:
|
61
|
-
:
|
62
|
-
:
|
54
|
+
search_command: 'UNSEEN',
|
55
|
+
delivery_method: 'postback',
|
56
|
+
host: 'imap.gmail.com',
|
57
|
+
port: 993,
|
58
|
+
ssl: true,
|
59
|
+
start_tls: false,
|
60
|
+
limit_max_unread: 0,
|
61
|
+
idle_timeout: IMAP_IDLE_TIMEOUT,
|
62
|
+
delete_after_delivery: false,
|
63
|
+
expunge_deleted: false,
|
64
|
+
delivery_options: {},
|
65
|
+
arbitration_method: 'noop',
|
66
|
+
arbitration_options: {},
|
67
|
+
logger: {}
|
63
68
|
}
|
64
69
|
|
65
70
|
# Store the configuration and require the appropriate delivery method
|
@@ -122,14 +127,32 @@ module MailRoom
|
|
122
127
|
{ email: self.email, name: self.name }
|
123
128
|
end
|
124
129
|
|
130
|
+
def imap?
|
131
|
+
!microsoft_graph?
|
132
|
+
end
|
133
|
+
|
134
|
+
def microsoft_graph?
|
135
|
+
self[:inbox_method].to_s == 'microsoft_graph'
|
136
|
+
end
|
137
|
+
|
125
138
|
def validate!
|
139
|
+
if microsoft_graph?
|
140
|
+
validate_microsoft_graph!
|
141
|
+
else
|
142
|
+
validate_imap!
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
private
|
147
|
+
|
148
|
+
def validate_imap!
|
126
149
|
if self[:idle_timeout] > IMAP_IDLE_TIMEOUT
|
127
150
|
raise IdleTimeoutTooLarge,
|
128
151
|
"Please use an idle timeout smaller than #{29*60} to prevent " \
|
129
152
|
"IMAP server disconnects"
|
130
153
|
end
|
131
154
|
|
132
|
-
|
155
|
+
IMAP_CONFIGURATION.each do |k|
|
133
156
|
if self[k].nil?
|
134
157
|
raise ConfigurationError,
|
135
158
|
"Field :#{k} is required in Mailbox: #{inspect}"
|
@@ -137,7 +160,23 @@ module MailRoom
|
|
137
160
|
end
|
138
161
|
end
|
139
162
|
|
140
|
-
|
163
|
+
def validate_microsoft_graph!
|
164
|
+
raise ConfigurationError, "Missing inbox_options in Mailbox: #{inspect}" unless self.inbox_options.is_a?(Hash)
|
165
|
+
|
166
|
+
MICROSOFT_GRAPH_CONFIGURATION.each do |k|
|
167
|
+
if self[k].nil?
|
168
|
+
raise ConfigurationError,
|
169
|
+
"Field :#{k} is required in Mailbox: #{inspect}"
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
MICROSOFT_GRAPH_INBOX_OPTIONS.each do |k|
|
174
|
+
if self[:inbox_options][k].nil?
|
175
|
+
raise ConfigurationError,
|
176
|
+
"inbox_options field :#{k} is required in Mailbox: #{inspect}"
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
141
180
|
|
142
181
|
def parsed_arbitration_options
|
143
182
|
arbitration_klass::Options.new(self)
|
@@ -62,8 +62,14 @@ module MailRoom
|
|
62
62
|
end
|
63
63
|
|
64
64
|
private
|
65
|
+
|
65
66
|
def connection
|
66
|
-
@connection ||=
|
67
|
+
@connection ||=
|
68
|
+
if @mailbox.microsoft_graph?
|
69
|
+
::MailRoom::MicrosoftGraph::Connection.new(@mailbox)
|
70
|
+
else
|
71
|
+
::MailRoom::IMAP::Connection.new(@mailbox)
|
72
|
+
end
|
67
73
|
end
|
68
74
|
end
|
69
75
|
end
|
@@ -0,0 +1,217 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
require 'oauth2'
|
5
|
+
|
6
|
+
module MailRoom
|
7
|
+
module MicrosoftGraph
|
8
|
+
class Connection < MailRoom::Connection
|
9
|
+
SCOPE = 'https://graph.microsoft.com/.default'
|
10
|
+
NEXT_PAGE_KEY = '@odata.nextLink'
|
11
|
+
DEFAULT_POLL_INTERVAL_S = 60
|
12
|
+
|
13
|
+
TooManyRequestsError = Class.new(RuntimeError)
|
14
|
+
|
15
|
+
attr_accessor :token, :throttled_count
|
16
|
+
|
17
|
+
def initialize(mailbox)
|
18
|
+
super
|
19
|
+
|
20
|
+
reset
|
21
|
+
setup
|
22
|
+
end
|
23
|
+
|
24
|
+
def wait
|
25
|
+
process_mailbox
|
26
|
+
|
27
|
+
@throttled_count = 0
|
28
|
+
wait_for_new_messages
|
29
|
+
rescue TooManyRequestsError => e
|
30
|
+
@throttled_count += 1
|
31
|
+
|
32
|
+
@mailbox.logger.warn({ context: @mailbox.context, action: 'Too many requests, backing off...', backoff_s: backoff_secs, error: e.message, error_backtrace: e.backtrace })
|
33
|
+
|
34
|
+
backoff
|
35
|
+
rescue IOError => e
|
36
|
+
@mailbox.logger.warn({ context: @mailbox.context, action: 'Disconnected. Resetting...', error: e.message, error_backtrace: e.backtrace })
|
37
|
+
|
38
|
+
reset
|
39
|
+
setup
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def wait_for_new_messages
|
45
|
+
sleep poll_interval
|
46
|
+
end
|
47
|
+
|
48
|
+
def backoff
|
49
|
+
sleep backoff_secs
|
50
|
+
end
|
51
|
+
|
52
|
+
def backoff_secs
|
53
|
+
[60 * 10, 2**throttled_count].min
|
54
|
+
end
|
55
|
+
|
56
|
+
def reset
|
57
|
+
@token = nil
|
58
|
+
@throttled_count = 0
|
59
|
+
end
|
60
|
+
|
61
|
+
def setup
|
62
|
+
@mailbox.logger.info({ context: @mailbox.context, action: 'Retrieving OAuth2 token...' })
|
63
|
+
|
64
|
+
@token = client.client_credentials.get_token({ scope: SCOPE })
|
65
|
+
end
|
66
|
+
|
67
|
+
def client
|
68
|
+
@client ||= OAuth2::Client.new(client_id, client_secret,
|
69
|
+
site: 'https://login.microsoftonline.com',
|
70
|
+
authorize_url: "/#{tenant_id}/oauth2/v2.0/authorize",
|
71
|
+
token_url: "/#{tenant_id}/oauth2/v2.0/token",
|
72
|
+
auth_scheme: :basic_auth)
|
73
|
+
end
|
74
|
+
|
75
|
+
def inbox_options
|
76
|
+
mailbox.inbox_options
|
77
|
+
end
|
78
|
+
|
79
|
+
def tenant_id
|
80
|
+
inbox_options[:tenant_id]
|
81
|
+
end
|
82
|
+
|
83
|
+
def client_id
|
84
|
+
inbox_options[:client_id]
|
85
|
+
end
|
86
|
+
|
87
|
+
def client_secret
|
88
|
+
inbox_options[:client_secret]
|
89
|
+
end
|
90
|
+
|
91
|
+
def poll_interval
|
92
|
+
@poll_interval ||= begin
|
93
|
+
interval = inbox_options[:poll_interval].to_i
|
94
|
+
|
95
|
+
if interval.positive?
|
96
|
+
interval
|
97
|
+
else
|
98
|
+
DEFAULT_POLL_INTERVAL_S
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def process_mailbox
|
104
|
+
return unless @new_message_handler
|
105
|
+
|
106
|
+
@mailbox.logger.info({ context: @mailbox.context, action: 'Processing started' })
|
107
|
+
|
108
|
+
new_messages.each do |msg|
|
109
|
+
success = @new_message_handler.call(msg)
|
110
|
+
handle_delivered(msg) if success
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def handle_delivered(msg)
|
115
|
+
mark_as_read(msg)
|
116
|
+
delete_message(msg) if @mailbox.delete_after_delivery
|
117
|
+
end
|
118
|
+
|
119
|
+
def delete_message(msg)
|
120
|
+
token.delete(msg_url(msg.uid))
|
121
|
+
end
|
122
|
+
|
123
|
+
def mark_as_read(msg)
|
124
|
+
token.patch(msg_url(msg.uid),
|
125
|
+
headers: { 'Content-Type' => 'application/json' },
|
126
|
+
body: { isRead: true }.to_json)
|
127
|
+
end
|
128
|
+
|
129
|
+
def new_messages
|
130
|
+
messages_for_ids(new_message_ids)
|
131
|
+
end
|
132
|
+
|
133
|
+
# Yields a page of message IDs at a time
|
134
|
+
def new_message_ids
|
135
|
+
url = unread_messages_url
|
136
|
+
|
137
|
+
Enumerator.new do |block|
|
138
|
+
loop do
|
139
|
+
messages, next_page_url = unread_messages(url: url)
|
140
|
+
messages.each { |msg| block.yield msg }
|
141
|
+
|
142
|
+
break unless next_page_url
|
143
|
+
|
144
|
+
url = next_page_url
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
def unread_messages(url:)
|
150
|
+
body = get(url)
|
151
|
+
|
152
|
+
return [[], nil] unless body
|
153
|
+
|
154
|
+
all_unread = body['value'].map { |msg| msg['id'] }
|
155
|
+
to_deliver = all_unread.select { |uid| @mailbox.deliver?(uid) }
|
156
|
+
@mailbox.logger.info({ context: @mailbox.context, action: 'Getting new messages',
|
157
|
+
unread: { count: all_unread.count, ids: all_unread },
|
158
|
+
to_be_delivered: { count: to_deliver.count, ids: to_deliver } })
|
159
|
+
[to_deliver, body[NEXT_PAGE_KEY]]
|
160
|
+
rescue TypeError, JSON::ParserError => e
|
161
|
+
log_exception('Error parsing JSON response', e)
|
162
|
+
[[], nil]
|
163
|
+
end
|
164
|
+
|
165
|
+
# Returns the JSON response
|
166
|
+
def get(url)
|
167
|
+
response = token.get(url, { raise_errors: false })
|
168
|
+
|
169
|
+
# https://docs.microsoft.com/en-us/graph/errors
|
170
|
+
case response.status
|
171
|
+
when 509, 429
|
172
|
+
raise TooManyRequestsError
|
173
|
+
when 400..599
|
174
|
+
raise OAuth2::Error, response
|
175
|
+
end
|
176
|
+
|
177
|
+
return unless response.body
|
178
|
+
|
179
|
+
body = JSON.parse(response.body)
|
180
|
+
|
181
|
+
raise TypeError, 'Response did not contain value hash' unless body.is_a?(Hash) && body.key?('value')
|
182
|
+
|
183
|
+
body
|
184
|
+
end
|
185
|
+
|
186
|
+
def messages_for_ids(message_ids)
|
187
|
+
message_ids.each_with_object([]) do |id, arr|
|
188
|
+
response = token.get(rfc822_msg_url(id))
|
189
|
+
|
190
|
+
arr << ::MailRoom::Message.new(uid: id, body: response.body)
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
def base_url
|
195
|
+
"https://graph.microsoft.com/v1.0/users/#{mailbox.email}/mailFolders/#{mailbox.name}/messages"
|
196
|
+
end
|
197
|
+
|
198
|
+
def unread_messages_url
|
199
|
+
"#{base_url}?$filter=isRead eq false"
|
200
|
+
end
|
201
|
+
|
202
|
+
def msg_url(id)
|
203
|
+
# Attempting to use the base_url fails with "The OData request is not supported"
|
204
|
+
"https://graph.microsoft.com/v1.0/users/#{mailbox.email}/messages/#{id}"
|
205
|
+
end
|
206
|
+
|
207
|
+
def rfc822_msg_url(id)
|
208
|
+
# Attempting to use the base_url fails with "The OData request is not supported"
|
209
|
+
"#{msg_url(id)}/$value"
|
210
|
+
end
|
211
|
+
|
212
|
+
def log_exception(message, exception)
|
213
|
+
@mailbox.logger.warn({ context: @mailbox.context, message: message, exception: exception.to_s })
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|
217
|
+
end
|
data/lib/mail_room/version.rb
CHANGED
data/mail_room.gemspec
CHANGED
@@ -18,9 +18,14 @@ Gem::Specification.new do |gem|
|
|
18
18
|
gem.require_paths = ["lib"]
|
19
19
|
|
20
20
|
gem.add_dependency "net-imap", ">= 0.2.1"
|
21
|
+
gem.add_dependency "oauth2", "~> 1.4.4"
|
22
|
+
|
23
|
+
# Pinning io-wait to 0.1.0, which is the last version to support Ruby < 3
|
24
|
+
gem.add_dependency "io-wait", "~> 0.1.0"
|
21
25
|
|
22
26
|
gem.add_development_dependency "rake"
|
23
27
|
gem.add_development_dependency "rspec", "~> 3.9"
|
28
|
+
gem.add_development_dependency "rubocop", "~> 1.11"
|
24
29
|
gem.add_development_dependency "mocha", "~> 1.11"
|
25
30
|
gem.add_development_dependency "simplecov"
|
26
31
|
gem.add_development_dependency "webrick", "~> 1.6"
|
@@ -33,4 +38,5 @@ Gem::Specification.new do |gem|
|
|
33
38
|
gem.add_development_dependency "redis-namespace"
|
34
39
|
gem.add_development_dependency "pg"
|
35
40
|
gem.add_development_dependency "charlock_holmes"
|
41
|
+
gem.add_development_dependency "webmock"
|
36
42
|
end
|
data/spec/lib/cli_spec.rb
CHANGED
@@ -2,8 +2,8 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe MailRoom::CLI do
|
4
4
|
let(:config_path) {File.expand_path('../fixtures/test_config.yml', File.dirname(__FILE__))}
|
5
|
-
let!(:configuration) {MailRoom::Configuration.new({:
|
6
|
-
let(:coordinator) {stub(:
|
5
|
+
let!(:configuration) {MailRoom::Configuration.new({config_path: config_path})}
|
6
|
+
let(:coordinator) {stub(run: true, quit: true)}
|
7
7
|
let(:configuration_args) { anything }
|
8
8
|
let(:coordinator_args) { [anything, anything] }
|
9
9
|
|
@@ -17,7 +17,7 @@ describe MailRoom::CLI do
|
|
17
17
|
|
18
18
|
context 'with configuration args' do
|
19
19
|
let(:configuration_args) do
|
20
|
-
{:
|
20
|
+
{config_path: 'a path'}
|
21
21
|
end
|
22
22
|
|
23
23
|
it 'parses arguments into configuration' do
|
@@ -5,7 +5,7 @@ describe MailRoom::Configuration do
|
|
5
5
|
|
6
6
|
describe '#initalize' do
|
7
7
|
context 'with config_path' do
|
8
|
-
let(:configuration) { MailRoom::Configuration.new(:
|
8
|
+
let(:configuration) { MailRoom::Configuration.new(config_path: config_path) }
|
9
9
|
|
10
10
|
it 'parses yaml into mailbox objects' do
|
11
11
|
MailRoom::Mailbox.stubs(:new).returns('mailbox1', 'mailbox2')
|
@@ -3,7 +3,7 @@ require 'mail_room/delivery/letter_opener'
|
|
3
3
|
|
4
4
|
describe MailRoom::Delivery::LetterOpener do
|
5
5
|
describe '#deliver' do
|
6
|
-
let(:mailbox) {build_mailbox(:
|
6
|
+
let(:mailbox) {build_mailbox(location: '/tmp/somewhere')}
|
7
7
|
let(:delivery_method) {stub(:deliver!)}
|
8
8
|
let(:mail) {stub}
|
9
9
|
|
@@ -13,7 +13,7 @@ describe MailRoom::Delivery::LetterOpener do
|
|
13
13
|
end
|
14
14
|
|
15
15
|
it 'creates a new LetterOpener::DeliveryMethod' do
|
16
|
-
::LetterOpener::DeliveryMethod.expects(:new).with(:
|
16
|
+
::LetterOpener::DeliveryMethod.expects(:new).with(location: '/tmp/somewhere').returns(delivery_method)
|
17
17
|
|
18
18
|
MailRoom::Delivery::LetterOpener.new(mailbox).deliver('a message')
|
19
19
|
end
|
@@ -16,7 +16,7 @@ describe MailRoom::Delivery::Logger do
|
|
16
16
|
end
|
17
17
|
|
18
18
|
context "with a log path" do
|
19
|
-
let(:mailbox) {build_mailbox(:
|
19
|
+
let(:mailbox) {build_mailbox(log_path: '/var/log/mail-room.log')}
|
20
20
|
|
21
21
|
it 'creates a new file to append to' do
|
22
22
|
file = stub(:sync=)
|
@@ -5,8 +5,8 @@ describe MailRoom::Delivery::Postback do
|
|
5
5
|
describe '#deliver' do
|
6
6
|
context 'with token auth delivery' do
|
7
7
|
let(:mailbox) {build_mailbox({
|
8
|
-
:
|
9
|
-
:
|
8
|
+
delivery_url: 'http://localhost/inbox',
|
9
|
+
delivery_token: 'abcdefg'
|
10
10
|
})}
|
11
11
|
|
12
12
|
let(:delivery_options) {
|
@@ -30,10 +30,10 @@ describe MailRoom::Delivery::Postback do
|
|
30
30
|
|
31
31
|
context 'with basic auth delivery options' do
|
32
32
|
let(:mailbox) {build_mailbox({
|
33
|
-
:
|
34
|
-
:
|
35
|
-
:
|
36
|
-
:
|
33
|
+
delivery_options: {
|
34
|
+
url: 'http://localhost/inbox',
|
35
|
+
username: 'user1',
|
36
|
+
password: 'password123abc'
|
37
37
|
}
|
38
38
|
})}
|
39
39
|
|
@@ -57,11 +57,11 @@ describe MailRoom::Delivery::Postback do
|
|
57
57
|
|
58
58
|
context 'with content type in the delivery options' do
|
59
59
|
let(:mailbox) {build_mailbox({
|
60
|
-
:
|
61
|
-
:
|
62
|
-
:
|
63
|
-
:
|
64
|
-
:
|
60
|
+
delivery_options: {
|
61
|
+
url: 'http://localhost/inbox',
|
62
|
+
username: 'user1',
|
63
|
+
password: 'password123abc',
|
64
|
+
content_type: 'text/plain'
|
65
65
|
}
|
66
66
|
})}
|
67
67
|
|
@@ -8,23 +8,45 @@ describe MailRoom::Delivery::Sidekiq do
|
|
8
8
|
|
9
9
|
describe '#options' do
|
10
10
|
let(:redis_url) { 'redis://localhost' }
|
11
|
+
let(:redis_options) { { redis_url: redis_url } }
|
11
12
|
|
12
13
|
context 'when only redis_url is specified' do
|
13
14
|
let(:mailbox) {
|
14
15
|
build_mailbox(
|
15
16
|
delivery_method: :sidekiq,
|
16
|
-
delivery_options:
|
17
|
-
redis_url: redis_url
|
18
|
-
}
|
17
|
+
delivery_options: redis_options
|
19
18
|
)
|
20
19
|
}
|
21
20
|
|
22
|
-
|
23
|
-
|
21
|
+
context 'with simple redis url' do
|
22
|
+
it 'client has same specified redis_url' do
|
23
|
+
expect(redis.client.options[:url]).to eq(redis_url)
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'client is a instance of RedisNamespace class' do
|
27
|
+
expect(redis).to be_a ::Redis
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'connection has correct values' do
|
31
|
+
expect(redis.connection[:host]).to eq('localhost')
|
32
|
+
expect(redis.connection[:db]).to eq(0)
|
33
|
+
end
|
24
34
|
end
|
25
35
|
|
26
|
-
|
27
|
-
|
36
|
+
context 'with redis_db specified in options' do
|
37
|
+
before do
|
38
|
+
redis_options[:redis_db] = 4
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'client has correct redis_url' do
|
42
|
+
expect(redis.client.options[:url]).to eq(redis_url)
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
it 'connection has correct values' do
|
47
|
+
expect(redis.connection[:host]).to eq('localhost')
|
48
|
+
expect(redis.connection[:db]).to eq(4)
|
49
|
+
end
|
28
50
|
end
|
29
51
|
end
|
30
52
|
|