gitlab-mail_room 0.0.9 → 0.0.23

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.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/.gitlab/issue_templates/Default.md +9 -0
  3. data/.gitlab/issue_templates/Release.md +1 -0
  4. data/.gitlab-ci.yml +14 -24
  5. data/.rubocop.yml +5 -0
  6. data/.rubocop_todo.yml +494 -0
  7. data/.ruby-version +1 -1
  8. data/.travis.yml +12 -5
  9. data/CHANGELOG.md +4 -0
  10. data/CONTRIBUTING.md +40 -0
  11. data/README.md +125 -14
  12. data/Rakefile +1 -1
  13. data/lib/mail_room/arbitration/redis.rb +1 -1
  14. data/lib/mail_room/connection.rb +6 -1
  15. data/lib/mail_room/crash_handler.rb +2 -1
  16. data/lib/mail_room/delivery/letter_opener.rb +1 -1
  17. data/lib/mail_room/delivery/postback.rb +42 -6
  18. data/lib/mail_room/delivery/que.rb +15 -1
  19. data/lib/mail_room/delivery/sidekiq.rb +4 -3
  20. data/lib/mail_room/jwt.rb +39 -0
  21. data/lib/mail_room/logger/structured.rb +15 -1
  22. data/lib/mail_room/mailbox.rb +56 -17
  23. data/lib/mail_room/mailbox_watcher.rb +7 -1
  24. data/lib/mail_room/microsoft_graph/connection.rb +243 -0
  25. data/lib/mail_room/microsoft_graph.rb +7 -0
  26. data/lib/mail_room/version.rb +1 -1
  27. data/mail_room.gemspec +7 -1
  28. data/spec/fixtures/jwt_secret +1 -0
  29. data/spec/lib/arbitration/redis_spec.rb +6 -5
  30. data/spec/lib/cli_spec.rb +3 -3
  31. data/spec/lib/configuration_spec.rb +1 -1
  32. data/spec/lib/delivery/letter_opener_spec.rb +4 -3
  33. data/spec/lib/delivery/logger_spec.rb +3 -2
  34. data/spec/lib/delivery/postback_spec.rb +62 -14
  35. data/spec/lib/delivery/sidekiq_spec.rb +33 -11
  36. data/spec/lib/jwt_spec.rb +80 -0
  37. data/spec/lib/logger/structured_spec.rb +34 -2
  38. data/spec/lib/mailbox_spec.rb +65 -17
  39. data/spec/lib/mailbox_watcher_spec.rb +54 -38
  40. data/spec/lib/microsoft_graph/connection_spec.rb +252 -0
  41. data/spec/spec_helper.rb +14 -3
  42. metadata +97 -8
@@ -5,6 +5,7 @@ describe MailRoom::Logger::Structured do
5
5
  subject { described_class.new $stdout }
6
6
 
7
7
  let!(:now) { Time.now }
8
+ let(:timestamp) { now.to_datetime.iso8601(3) }
8
9
  let(:message) { { action: 'exciting development', message: 'testing 123' } }
9
10
 
10
11
  before do
@@ -32,7 +33,7 @@ describe MailRoom::Logger::Structured do
32
33
  }
33
34
  expected = {
34
35
  severity: 'DEBUG',
35
- time: now,
36
+ time: timestamp,
36
37
  additional_field: "some value"
37
38
  }
38
39
 
@@ -40,10 +41,41 @@ describe MailRoom::Logger::Structured do
40
41
  end
41
42
  end
42
43
 
44
+ describe '#format_message' do
45
+ shared_examples 'timestamp formatting' do
46
+ it 'outputs ISO8601 timestamps' do
47
+ data = JSON.parse(subject.format_message('debug', input_timestamp, 'test', { message: 'hello' } ))
48
+
49
+ expect(data['time']).to eq(expected_timestamp)
50
+ end
51
+ end
52
+
53
+ context 'with no timestamp' do
54
+ let(:input_timestamp) { nil }
55
+ let(:expected_timestamp) { timestamp }
56
+
57
+ it_behaves_like 'timestamp formatting'
58
+ end
59
+
60
+ context 'with DateTime' do
61
+ let(:input_timestamp) { now.to_datetime }
62
+ let(:expected_timestamp) { timestamp }
63
+
64
+ it_behaves_like 'timestamp formatting'
65
+ end
66
+
67
+ context 'with string' do
68
+ let(:input_timestamp) { now.to_s }
69
+ let(:expected_timestamp) { input_timestamp }
70
+
71
+ it_behaves_like 'timestamp formatting'
72
+ end
73
+ end
74
+
43
75
  def json_matching(level, message)
44
76
  contents = {
45
77
  severity: level,
46
- time: now
78
+ time: timestamp
47
79
  }.merge(message)
48
80
 
49
81
  as_regex(contents)
@@ -3,12 +3,23 @@ require 'spec_helper'
3
3
  describe MailRoom::Mailbox do
4
4
  let(:sample_message) { MailRoom::Message.new(uid: 123, body: 'a message') }
5
5
 
6
+ context 'with IMAP configuration' do
7
+ subject { build_mailbox }
8
+
9
+ describe '#imap?' do
10
+ it 'configured as an IMAP inbox' do
11
+ expect(subject.imap?).to be true
12
+ expect(subject.microsoft_graph?).to be false
13
+ end
14
+ end
15
+ end
16
+
6
17
  describe "#deliver" do
7
18
  context "with arbitration_method of noop" do
8
19
  it 'arbitrates with a Noop instance' do
9
- mailbox = build_mailbox({:arbitration_method => 'noop'})
20
+ mailbox = build_mailbox({arbitration_method: 'noop'})
10
21
  noop = stub(:deliver?)
11
- MailRoom::Arbitration['noop'].stubs(:new => noop)
22
+ MailRoom::Arbitration['noop'].stubs(new: noop)
12
23
 
13
24
  uid = 123
14
25
 
@@ -20,9 +31,9 @@ describe MailRoom::Mailbox do
20
31
 
21
32
  context "with arbitration_method of redis" do
22
33
  it 'arbitrates with a Redis instance' do
23
- mailbox = build_mailbox({:arbitration_method => 'redis'})
34
+ mailbox = build_mailbox({arbitration_method: 'redis'})
24
35
  redis = stub(:deliver?)
25
- MailRoom::Arbitration['redis'].stubs(:new => redis)
36
+ MailRoom::Arbitration['redis'].stubs(new: redis)
26
37
  uid = 123
27
38
  redis.expects(:deliver?).with(uid)
28
39
 
@@ -32,9 +43,9 @@ describe MailRoom::Mailbox do
32
43
 
33
44
  context "with delivery_method of noop" do
34
45
  it 'delivers with a Noop instance' do
35
- mailbox = build_mailbox({:delivery_method => 'noop'})
46
+ mailbox = build_mailbox({delivery_method: 'noop'})
36
47
  noop = stub(:deliver)
37
- MailRoom::Delivery['noop'].stubs(:new => noop)
48
+ MailRoom::Delivery['noop'].stubs(new: noop)
38
49
 
39
50
  noop.expects(:deliver).with(sample_message.body)
40
51
 
@@ -44,9 +55,9 @@ describe MailRoom::Mailbox do
44
55
 
45
56
  context "with delivery_method of logger" do
46
57
  it 'delivers with a Logger instance' do
47
- mailbox = build_mailbox({:delivery_method => 'logger'})
58
+ mailbox = build_mailbox({delivery_method: 'logger'})
48
59
  logger = stub(:deliver)
49
- MailRoom::Delivery['logger'].stubs(:new => logger)
60
+ MailRoom::Delivery['logger'].stubs(new: logger)
50
61
 
51
62
  logger.expects(:deliver).with(sample_message.body)
52
63
 
@@ -56,9 +67,9 @@ describe MailRoom::Mailbox do
56
67
 
57
68
  context "with delivery_method of postback" do
58
69
  it 'delivers with a Postback instance' do
59
- mailbox = build_mailbox({:delivery_method => 'postback'})
70
+ mailbox = build_mailbox({delivery_method: 'postback'})
60
71
  postback = stub(:deliver)
61
- MailRoom::Delivery['postback'].stubs(:new => postback)
72
+ MailRoom::Delivery['postback'].stubs(new: postback)
62
73
 
63
74
  postback.expects(:deliver).with(sample_message.body)
64
75
 
@@ -68,9 +79,9 @@ describe MailRoom::Mailbox do
68
79
 
69
80
  context "with delivery_method of letter_opener" do
70
81
  it 'delivers with a LetterOpener instance' do
71
- mailbox = build_mailbox({:delivery_method => 'letter_opener'})
82
+ mailbox = build_mailbox({delivery_method: 'letter_opener'})
72
83
  letter_opener = stub(:deliver)
73
- MailRoom::Delivery['letter_opener'].stubs(:new => letter_opener)
84
+ MailRoom::Delivery['letter_opener'].stubs(new: letter_opener)
74
85
 
75
86
  letter_opener.expects(:deliver).with(sample_message.body)
76
87
 
@@ -82,7 +93,7 @@ describe MailRoom::Mailbox do
82
93
  it "doesn't deliver the message" do
83
94
  mailbox = build_mailbox({ name: "magic mailbox", delivery_method: 'noop' })
84
95
  noop = stub(:deliver)
85
- MailRoom::Delivery['noop'].stubs(:new => noop)
96
+ MailRoom::Delivery['noop'].stubs(new: noop)
86
97
  noop.expects(:deliver).never
87
98
 
88
99
  mailbox.deliver(MailRoom::Message.new(uid: 1234, body: nil))
@@ -91,9 +102,9 @@ describe MailRoom::Mailbox do
91
102
 
92
103
  context "with ssl options hash" do
93
104
  it 'replaces verify mode with constant' do
94
- mailbox = build_mailbox({:ssl => {:verify_mode => :none}})
105
+ mailbox = build_mailbox({ssl: {verify_mode: :none}})
95
106
 
96
- expect(mailbox.ssl_options).to eq({:verify_mode => OpenSSL::SSL::VERIFY_NONE})
107
+ expect(mailbox.ssl_options).to eq({verify_mode: OpenSSL::SSL::VERIFY_NONE})
97
108
  end
98
109
  end
99
110
 
@@ -121,8 +132,45 @@ describe MailRoom::Mailbox do
121
132
  describe "#validate!" do
122
133
  context "with missing configuration" do
123
134
  it 'raises an error' do
124
- expect { build_mailbox({:name => nil}) }.to raise_error(MailRoom::ConfigurationError)
125
- expect { build_mailbox({:host => nil}) }.to raise_error(MailRoom::ConfigurationError)
135
+ expect { build_mailbox({name: nil}) }.to raise_error(MailRoom::ConfigurationError)
136
+ expect { build_mailbox({host: nil}) }.to raise_error(MailRoom::ConfigurationError)
137
+ end
138
+ end
139
+
140
+ context "with Microsoft Graph configuration" do
141
+ let(:options) do
142
+ {
143
+ arbitration_method: 'redis',
144
+ }.merge(REQUIRED_MICROSOFT_GRAPH_DEFAULTS)
145
+ end
146
+
147
+ subject { build_mailbox(options) }
148
+
149
+ def delete_inbox_option(key)
150
+ options[:inbox_options] = options[:inbox_options].dup.delete(key)
151
+ end
152
+
153
+ it 'allows password omission' do
154
+ expect { subject }.not_to raise_error
155
+ end
156
+
157
+ it 'configured as a Microsoft Graph inbox' do
158
+ expect(subject.imap?).to be false
159
+ expect(subject.microsoft_graph?).to be true
160
+ end
161
+
162
+ it 'raises an error when the inbox options are not present' do
163
+ options.delete(:inbox_options)
164
+
165
+ expect { subject }.to raise_error(MailRoom::ConfigurationError)
166
+ end
167
+
168
+ %i[tenant_id client_id client_secret].each do |item|
169
+ it "raises an error when the #{item} is not present" do
170
+ delete_inbox_option(item)
171
+
172
+ expect { subject }.to raise_error(MailRoom::ConfigurationError)
173
+ end
126
174
  end
127
175
  end
128
176
  end
@@ -1,61 +1,77 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe MailRoom::MailboxWatcher do
4
- let(:mailbox) {build_mailbox}
5
-
6
- describe '#running?' do
7
- it 'is false by default' do
8
- watcher = MailRoom::MailboxWatcher.new(mailbox)
9
- expect(watcher.running?).to eq(false)
4
+ context 'with IMAP configured' do
5
+ let(:mailbox) {build_mailbox}
6
+
7
+ describe '#running?' do
8
+ it 'is false by default' do
9
+ watcher = MailRoom::MailboxWatcher.new(mailbox)
10
+ expect(watcher.running?).to eq(false)
11
+ end
10
12
  end
11
- end
12
13
 
13
- describe '#run' do
14
- let(:imap) {stub(:login => true, :select => true)}
15
- let(:watcher) {MailRoom::MailboxWatcher.new(mailbox)}
14
+ describe '#run' do
15
+ let(:imap) {stub(login: true, select: true)}
16
+ let(:watcher) {MailRoom::MailboxWatcher.new(mailbox)}
16
17
 
17
- before :each do
18
- Net::IMAP.stubs(:new).returns(imap) # prevent connection
19
- end
18
+ before :each do
19
+ Net::IMAP.stubs(:new).returns(imap) # prevent connection
20
+ end
20
21
 
21
- it 'loops over wait while running' do
22
- connection = MailRoom::IMAP::Connection.new(mailbox)
22
+ it 'loops over wait while running' do
23
+ connection = MailRoom::IMAP::Connection.new(mailbox)
23
24
 
24
- MailRoom::IMAP::Connection.stubs(:new).returns(connection)
25
+ MailRoom::IMAP::Connection.stubs(:new).returns(connection)
25
26
 
26
- watcher.expects(:running?).twice.returns(true, false)
27
- connection.expects(:wait).once
28
- connection.expects(:on_new_message).once
27
+ watcher.expects(:running?).twice.returns(true, false)
28
+ connection.expects(:wait).once
29
+ connection.expects(:on_new_message).once
29
30
 
30
- watcher.run
31
- watcher.watching_thread.join # wait for finishing run
31
+ watcher.run
32
+ watcher.watching_thread.join # wait for finishing run
33
+ end
32
34
  end
33
- end
34
35
 
35
- describe '#quit' do
36
- let(:imap) {stub(:login => true, :select => true)}
37
- let(:watcher) {MailRoom::MailboxWatcher.new(mailbox)}
36
+ describe '#quit' do
37
+ let(:imap) {stub(login: true, select: true)}
38
+ let(:watcher) {MailRoom::MailboxWatcher.new(mailbox)}
38
39
 
39
- before :each do
40
- Net::IMAP.stubs(:new).returns(imap) # prevent connection
41
- end
40
+ before :each do
41
+ Net::IMAP.stubs(:new).returns(imap) # prevent connection
42
+ end
43
+
44
+ it 'closes and waits for the connection' do
45
+ connection = MailRoom::IMAP::Connection.new(mailbox)
46
+ connection.stubs(:wait)
47
+ connection.stubs(:quit)
42
48
 
43
- it 'closes and waits for the connection' do
44
- connection = MailRoom::IMAP::Connection.new(mailbox)
45
- connection.stubs(:wait)
46
- connection.stubs(:quit)
49
+ MailRoom::IMAP::Connection.stubs(:new).returns(connection)
47
50
 
48
- MailRoom::IMAP::Connection.stubs(:new).returns(connection)
51
+ watcher.run
52
+
53
+ expect(watcher.running?).to eq(true)
54
+
55
+ connection.expects(:quit)
56
+
57
+ watcher.quit
58
+
59
+ expect(watcher.running?).to eq(false)
60
+ end
61
+ end
62
+ end
49
63
 
50
- watcher.run
64
+ context 'with Microsoft Graph configured' do
65
+ let(:mailbox) { build_mailbox(REQUIRED_MICROSOFT_GRAPH_DEFAULTS) }
51
66
 
52
- expect(watcher.running?).to eq(true)
67
+ subject { described_class.new(mailbox) }
53
68
 
54
- connection.expects(:quit)
69
+ it 'initializes a Microsoft Graph connection' do
70
+ connection = stub(on_new_message: nil)
55
71
 
56
- watcher.quit
72
+ MailRoom::MicrosoftGraph::Connection.stubs(:new).returns(connection)
57
73
 
58
- expect(watcher.running?).to eq(false)
74
+ expect(subject.send(:connection)).to eq(connection)
59
75
  end
60
76
  end
61
77
  end
@@ -0,0 +1,252 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'securerandom'
4
+ require 'spec_helper'
5
+ require 'json'
6
+ require 'webmock/rspec'
7
+
8
+ describe MailRoom::MicrosoftGraph::Connection do
9
+ let(:tenant_id) { options[:inbox_options][:tenant_id] }
10
+ let(:options) do
11
+ {
12
+ delete_after_delivery: true,
13
+ expunge_deleted: true
14
+ }.merge(REQUIRED_MICROSOFT_GRAPH_DEFAULTS)
15
+ end
16
+ let(:mailbox) { build_mailbox(options) }
17
+ let(:graph_endpoint) { 'https://graph.microsoft.com' }
18
+ let(:azure_ad_endpoint) { 'https://login.microsoftonline.com' }
19
+ let(:base_url) { "#{graph_endpoint}/v1.0/users/user@example.com/mailFolders/inbox/messages" }
20
+ let(:message_base_url) { "#{graph_endpoint}/v1.0/users/user@example.com/messages" }
21
+
22
+ let(:connection) { described_class.new(mailbox) }
23
+ let(:uid) { 1 }
24
+ let(:access_token) { SecureRandom.hex }
25
+ let(:refresh_token) { SecureRandom.hex }
26
+ let(:expires_in) { Time.now + 3600 }
27
+ let(:unread_messages_body) { '' }
28
+ let(:status) { 200 }
29
+ let!(:stub_token) do
30
+ stub_request(:post, "#{azure_ad_endpoint}/#{tenant_id}/oauth2/v2.0/token").to_return(
31
+ body: { 'access_token' => access_token, 'refresh_token' => refresh_token, 'expires_in' => expires_in }.to_json,
32
+ headers: { 'Content-Type' => 'application/json' }
33
+ )
34
+ end
35
+ let!(:stub_unread_messages_request) do
36
+ stub_request(:get, "#{base_url}?$filter=isRead%20eq%20false").to_return(
37
+ status: status,
38
+ body: unread_messages_body.to_json,
39
+ headers: { 'Content-Type' => 'application/json' }
40
+ )
41
+ end
42
+
43
+ before do
44
+ WebMock.enable!
45
+ end
46
+
47
+ context '#quit' do
48
+ it 'returns false' do
49
+ expect(connection.stopped?).to be_falsey
50
+ end
51
+
52
+ it 'returns true' do
53
+ connection.quit
54
+
55
+ expect(connection.stopped?).to be_truthy
56
+ end
57
+
58
+ it 'does not attempt to process the mailbox' do
59
+ connection.quit
60
+
61
+ connection.expects(:process_mailbox).times(0)
62
+ connection.wait
63
+ end
64
+ end
65
+
66
+ context '#wait' do
67
+ before do
68
+ connection.stubs(:do_sleep)
69
+ end
70
+
71
+ describe 'poll interval' do
72
+ it 'defaults to 60 seconds' do
73
+ expect(connection.send(:poll_interval)).to eq(60)
74
+ end
75
+
76
+ it 'calls do_sleep 60 times' do
77
+ connection.expects(:do_sleep).with(1).times(60)
78
+
79
+ connection.wait
80
+ end
81
+
82
+ context 'interval set to 10' do
83
+ let(:options) do
84
+ {
85
+ inbox_method: :microsoft_graph,
86
+ inbox_options: {
87
+ tenant_id: '98776',
88
+ client_id: '12345',
89
+ client_secret: 'MY-SECRET',
90
+ poll_interval: '10'
91
+ }
92
+ }
93
+ end
94
+
95
+ it 'sets the poll interval to 10' do
96
+ expect(connection.send(:poll_interval)).to eq(10)
97
+ end
98
+
99
+ it 'calls do_sleep 10 times' do
100
+ connection.expects(:do_sleep).with(1).times(10)
101
+
102
+ connection.wait
103
+ end
104
+ end
105
+ end
106
+
107
+ shared_examples 'with a single message' do
108
+ let(:message_id) { SecureRandom.hex }
109
+ let(:unread_messages_body) { { value: ['id' => message_id] } }
110
+ let(:message_url) { "#{message_base_url}/#{message_id}" }
111
+ let(:message_body) { 'hello world' }
112
+
113
+ it 'requests message ID' do
114
+ stub_get = stub_request(:get, "#{message_url}/$value").to_return(
115
+ status: 200,
116
+ body: message_body
117
+ )
118
+ stub_patch = stub_request(:patch, message_url).with(body: { "isRead": true }.to_json)
119
+ stub_delete = stub_request(:delete, message_url)
120
+ message_count = 0
121
+
122
+ connection.on_new_message do |message|
123
+ message_count += 1
124
+ expect(message.uid).to eq(message_id)
125
+ expect(message.body).to eq(message_body)
126
+ end
127
+
128
+ connection.wait
129
+
130
+ assert_requested(stub_token)
131
+ assert_requested(stub_unread_messages_request)
132
+ assert_requested(stub_get)
133
+ assert_requested(stub_patch)
134
+ assert_requested(stub_delete)
135
+ expect(message_count).to eq(1)
136
+ end
137
+ end
138
+
139
+ context 'with default Azure settings' do
140
+ before do
141
+ puts options
142
+ end
143
+ it_behaves_like 'with a single message'
144
+ end
145
+
146
+ # https://docs.microsoft.com/en-us/graph/deployments
147
+ context 'with an alternative Azure deployment' do
148
+ let(:graph_endpoint) { 'https://graph.microsoft.us' }
149
+ let(:azure_ad_endpoint) { 'https://login.microsoftonline.us' }
150
+ let(:options) do
151
+ {
152
+ inbox_method: :microsoft_graph,
153
+ delete_after_delivery: true,
154
+ expunge_deleted: true,
155
+ inbox_options: {
156
+ tenant_id: '98776',
157
+ client_id: '12345',
158
+ client_secret: 'MY-SECRET',
159
+ graph_endpoint: 'https://graph.microsoft.us',
160
+ azure_ad_endpoint: 'https://login.microsoftonline.us'
161
+ }
162
+ }
163
+ end
164
+
165
+ it_behaves_like 'with a single message'
166
+ end
167
+
168
+ context 'with multiple pages of messages' do
169
+ let(:message_ids) { [SecureRandom.hex, SecureRandom.hex] }
170
+ let(:next_page_url) { "#{graph_endpoint}/v1.0/nextPage" }
171
+ let(:unread_messages_body) { { value: ['id' => message_ids.first], '@odata.nextLink' => next_page_url } }
172
+ let(:message_body) { 'hello world' }
173
+
174
+ it 'requests message ID' do
175
+ stub_request(:get, next_page_url).to_return(
176
+ status: 200,
177
+ body: { value: ['id' => message_ids[1]] }.to_json
178
+ )
179
+
180
+ stubs = []
181
+ message_ids.each do |message_id|
182
+ rfc822_msg_url = "#{message_base_url}/#{message_id}/$value"
183
+ stubs << stub_request(:get, rfc822_msg_url).to_return(
184
+ status: 200,
185
+ body: message_body
186
+ )
187
+
188
+ msg_url = "#{message_base_url}/#{message_id}"
189
+ stubs << stub_request(:patch, msg_url).with(body: { "isRead": true }.to_json)
190
+ stubs << stub_request(:delete, msg_url)
191
+ end
192
+
193
+ message_count = 0
194
+
195
+ connection.on_new_message do |message|
196
+ expect(message.uid).to eq(message_ids[message_count])
197
+ expect(message.body).to eq(message_body)
198
+ message_count += 1
199
+ end
200
+
201
+ connection.wait
202
+
203
+ stubs.each { |stub| assert_requested(stub) }
204
+ expect(message_count).to eq(2)
205
+ end
206
+ end
207
+
208
+ shared_examples 'request backoff' do
209
+ it 'backs off' do
210
+ connection.expects(:backoff)
211
+
212
+ connection.on_new_message {}
213
+ connection.wait
214
+
215
+ expect(connection.throttled_count).to eq(1)
216
+ end
217
+ end
218
+
219
+ context 'too many requests' do
220
+ let(:status) { 429 }
221
+
222
+ it_behaves_like 'request backoff'
223
+ end
224
+
225
+ context 'too much bandwidth' do
226
+ let(:status) { 509 }
227
+
228
+ it_behaves_like 'request backoff'
229
+ end
230
+
231
+ context 'invalid JSON response' do
232
+ let(:body) { 'this is something' }
233
+
234
+ it 'ignores the message and logs a warning' do
235
+ mailbox.logger.expects(:warn)
236
+
237
+ connection.on_new_message {}
238
+ connection.wait
239
+ end
240
+ end
241
+
242
+ context '500 error' do
243
+ let(:status) { 500 }
244
+
245
+ it 'terminates due to error' do
246
+ connection.on_new_message {}
247
+
248
+ expect { connection.wait }.to raise_error(OAuth2::Error)
249
+ end
250
+ end
251
+ end
252
+ end
data/spec/spec_helper.rb CHANGED
@@ -2,6 +2,7 @@ require 'simplecov'
2
2
  SimpleCov.start
3
3
 
4
4
  require 'bundler/setup'
5
+ require 'date'
5
6
 
6
7
  require 'rspec'
7
8
  require 'mocha/api'
@@ -21,11 +22,21 @@ RSpec.configure do |config|
21
22
  end
22
23
 
23
24
  REQUIRED_MAILBOX_DEFAULTS = {
24
- :name => "inbox",
25
- :email => "user@example.com",
26
- :password => "password123"
25
+ name: "inbox",
26
+ email: "user@example.com",
27
+ password: "password123"
27
28
  }
28
29
 
30
+ REQUIRED_MICROSOFT_GRAPH_DEFAULTS = {
31
+ password: nil,
32
+ inbox_method: :microsoft_graph,
33
+ inbox_options: {
34
+ tenant_id: '98776',
35
+ client_id: '12345',
36
+ client_secret: 'MY-SECRET',
37
+ }.freeze
38
+ }.freeze
39
+
29
40
  def build_mailbox(options = {})
30
41
  MailRoom::Mailbox.new(REQUIRED_MAILBOX_DEFAULTS.merge(options))
31
42
  end