mail_room 0.7.0 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/lib/mail_room.rb +1 -1
- data/lib/mail_room/configuration.rb +1 -1
- data/lib/mail_room/connection.rb +175 -0
- data/lib/mail_room/coordinator.rb +2 -0
- data/lib/mail_room/mailbox_watcher.rb +17 -122
- data/lib/mail_room/version.rb +1 -1
- data/spec/lib/cli_spec.rb +5 -5
- data/spec/lib/configuration_spec.rb +3 -3
- data/spec/lib/connection_spec.rb +63 -0
- data/spec/lib/coordinator_spec.rb +10 -10
- data/spec/lib/delivery/letter_opener_spec.rb +3 -3
- data/spec/lib/delivery/logger_spec.rb +4 -4
- data/spec/lib/delivery/postback_spec.rb +4 -4
- data/spec/lib/mailbox_spec.rb +7 -7
- data/spec/lib/mailbox_watcher_spec.rb +25 -211
- data/spec/spec_helper.rb +0 -1
- metadata +5 -5
- data/lib/mail_room/mailbox_handler.rb +0 -59
- data/spec/lib/mailbox_handler_spec.rb +0 -57
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 86c8cfc70ff25a195a9e59c4bc175eb68b107874
|
4
|
+
data.tar.gz: 3bc4c8778f7ff9e14233986a922033243482902e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1f84614429adeb0e94e6b22bc053861ad10f939e551d370cbfa8e091306737628616a999ce1c42c7a879d4b67f8bea3d58e6620657e0d01676e1c8fe673d9c5b
|
7
|
+
data.tar.gz: ce3e8a096c013bda86d20e86f31fae1753fb2fff7da7fb74b5db72e59bb76325086bce87505ceeb7b7927b9f49efdae28c88c0d8af9732a3f12f90eab328d73a
|
data/CHANGELOG.md
CHANGED
data/lib/mail_room.rb
CHANGED
@@ -10,6 +10,6 @@ require "mail_room/backports/imap"
|
|
10
10
|
require "mail_room/configuration"
|
11
11
|
require "mail_room/mailbox"
|
12
12
|
require "mail_room/mailbox_watcher"
|
13
|
-
require "mail_room/
|
13
|
+
require "mail_room/connection"
|
14
14
|
require "mail_room/coordinator"
|
15
15
|
require "mail_room/cli"
|
@@ -4,7 +4,7 @@ module MailRoom
|
|
4
4
|
# Wraps configuration for a set of individual mailboxes with global config
|
5
5
|
# @author Tony Pitale
|
6
6
|
class Configuration
|
7
|
-
attr_accessor :mailboxes, :
|
7
|
+
attr_accessor :mailboxes, :log_path, :quiet
|
8
8
|
|
9
9
|
# Initialize a new configuration of mailboxes
|
10
10
|
def initialize(options={})
|
@@ -0,0 +1,175 @@
|
|
1
|
+
module MailRoom
|
2
|
+
class Connection
|
3
|
+
def initialize(mailbox)
|
4
|
+
@mailbox = mailbox
|
5
|
+
|
6
|
+
# log in and set the mailbox
|
7
|
+
reset
|
8
|
+
setup
|
9
|
+
end
|
10
|
+
|
11
|
+
def on_new_message(&block)
|
12
|
+
@new_message_handler = block
|
13
|
+
end
|
14
|
+
|
15
|
+
# is the connection logged in?
|
16
|
+
# @return [Boolean]
|
17
|
+
def logged_in?
|
18
|
+
@logged_in
|
19
|
+
end
|
20
|
+
|
21
|
+
# is the connection blocked idling?
|
22
|
+
# @return [Boolean]
|
23
|
+
def idling?
|
24
|
+
@idling
|
25
|
+
end
|
26
|
+
|
27
|
+
# is the imap connection closed?
|
28
|
+
# @return [Boolean]
|
29
|
+
def disconnected?
|
30
|
+
@imap.disconnected?
|
31
|
+
end
|
32
|
+
|
33
|
+
# is the connection ready to idle?
|
34
|
+
# @return [Boolean]
|
35
|
+
def ready_to_idle?
|
36
|
+
logged_in? && !idling?
|
37
|
+
end
|
38
|
+
|
39
|
+
def quit
|
40
|
+
stop_idling
|
41
|
+
reset
|
42
|
+
end
|
43
|
+
|
44
|
+
def wait
|
45
|
+
begin
|
46
|
+
# in case we missed any between idles
|
47
|
+
process_mailbox
|
48
|
+
|
49
|
+
idle
|
50
|
+
|
51
|
+
process_mailbox
|
52
|
+
rescue Net::IMAP::Error, IOError
|
53
|
+
reset
|
54
|
+
setup
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
def reset
|
61
|
+
@imap = nil
|
62
|
+
@logged_in = false
|
63
|
+
@idling = false
|
64
|
+
end
|
65
|
+
|
66
|
+
def setup
|
67
|
+
start_tls
|
68
|
+
log_in
|
69
|
+
set_mailbox
|
70
|
+
end
|
71
|
+
|
72
|
+
# build a net/imap connection to google imap
|
73
|
+
def imap
|
74
|
+
@imap ||= MailRoom::IMAP.new(@mailbox.host, :port => @mailbox.port, :ssl => @mailbox.ssl_options)
|
75
|
+
end
|
76
|
+
|
77
|
+
# start a TLS session
|
78
|
+
def start_tls
|
79
|
+
imap.starttls if @mailbox.start_tls
|
80
|
+
end
|
81
|
+
|
82
|
+
# send the imap login command to google
|
83
|
+
def log_in
|
84
|
+
imap.login(@mailbox.email, @mailbox.password)
|
85
|
+
@logged_in = true
|
86
|
+
end
|
87
|
+
|
88
|
+
# select the mailbox name we want to use
|
89
|
+
def set_mailbox
|
90
|
+
imap.select(@mailbox.name) if logged_in?
|
91
|
+
end
|
92
|
+
|
93
|
+
# is the response for a new message?
|
94
|
+
# @param response [Net::IMAP::TaggedResponse] the imap response from idle
|
95
|
+
# @return [Boolean]
|
96
|
+
def message_exists?(response)
|
97
|
+
response.respond_to?(:name) && response.name == 'EXISTS'
|
98
|
+
end
|
99
|
+
|
100
|
+
# @private
|
101
|
+
def idle_handler
|
102
|
+
lambda {|response| imap.idle_done if message_exists?(response)}
|
103
|
+
end
|
104
|
+
|
105
|
+
# maintain an imap idle connection
|
106
|
+
def idle
|
107
|
+
return unless ready_to_idle?
|
108
|
+
|
109
|
+
@idling = true
|
110
|
+
|
111
|
+
imap.idle(@mailbox.idle_timeout, &idle_handler)
|
112
|
+
ensure
|
113
|
+
@idling = false
|
114
|
+
end
|
115
|
+
|
116
|
+
# trigger the idle to finish and wait for the thread to finish
|
117
|
+
def stop_idling
|
118
|
+
return unless idling?
|
119
|
+
|
120
|
+
imap.idle_done
|
121
|
+
|
122
|
+
# idling_thread.join
|
123
|
+
# self.idling_thread = nil
|
124
|
+
end
|
125
|
+
|
126
|
+
def process_mailbox
|
127
|
+
return unless @new_message_handler
|
128
|
+
|
129
|
+
msgs = new_messages
|
130
|
+
|
131
|
+
msgs.
|
132
|
+
map(&@new_message_handler). # deliver each new message, collect success
|
133
|
+
zip(msgs). # include messages with success
|
134
|
+
select(&:first).map(&:last). # filter failed deliveries, collect message
|
135
|
+
each {|message| scrub(message)} # scrub delivered messages
|
136
|
+
end
|
137
|
+
|
138
|
+
def scrub(message)
|
139
|
+
if @mailbox.delete_after_delivery
|
140
|
+
imap.store(message.seqno, "+FLAGS", [Net::IMAP::DELETED])
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
# @private
|
145
|
+
# fetch all messages for the new message ids
|
146
|
+
def new_messages
|
147
|
+
# Both of these calls may results in
|
148
|
+
# imap raising an EOFError, we handle
|
149
|
+
# this exception in the watcher
|
150
|
+
messages_for_ids(new_message_ids)
|
151
|
+
end
|
152
|
+
|
153
|
+
# TODO: label messages?
|
154
|
+
# @imap.store(id, "+X-GM-LABELS", [label])
|
155
|
+
|
156
|
+
# @private
|
157
|
+
# search for all new (unseen) message ids
|
158
|
+
# @return [Array<Integer>] message ids
|
159
|
+
def new_message_ids
|
160
|
+
# uid_search still leaves messages UNSEEN
|
161
|
+
imap.uid_search(@mailbox.search_command).select { |uid| @mailbox.deliver?(uid) }
|
162
|
+
end
|
163
|
+
|
164
|
+
# @private
|
165
|
+
# fetch the email for all given ids in RFC822 format
|
166
|
+
# @param ids [Array<Integer>] list of message ids
|
167
|
+
# @return [Array<Net::IMAP::FetchData>] the net/imap messages for the given ids
|
168
|
+
def messages_for_ids(uids)
|
169
|
+
return [] if uids.empty?
|
170
|
+
|
171
|
+
# uid_fetch marks as SEEN, will not be re-fetched for UNSEEN
|
172
|
+
imap.uid_fetch(uids, "RFC822")
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
@@ -4,25 +4,15 @@ module MailRoom
|
|
4
4
|
# Watch a Mailbox
|
5
5
|
# @author Tony Pitale
|
6
6
|
class MailboxWatcher
|
7
|
-
attr_accessor :
|
7
|
+
attr_accessor :watching_thread
|
8
8
|
|
9
9
|
# Watch a new mailbox
|
10
10
|
# @param mailbox [MailRoom::Mailbox] the mailbox to watch
|
11
11
|
def initialize(mailbox)
|
12
12
|
@mailbox = mailbox
|
13
13
|
|
14
|
-
reset
|
15
14
|
@running = false
|
16
|
-
|
17
|
-
|
18
|
-
# build a net/imap connection to google imap
|
19
|
-
def imap
|
20
|
-
@imap ||= MailRoom::IMAP.new(@mailbox.host, :port => @mailbox.port, :ssl => @mailbox.ssl_options)
|
21
|
-
end
|
22
|
-
|
23
|
-
# build a handler to process mailbox messages
|
24
|
-
def handler
|
25
|
-
@handler ||= MailboxHandler.new(@mailbox, imap)
|
15
|
+
@connection = nil
|
26
16
|
end
|
27
17
|
|
28
18
|
# are we running?
|
@@ -31,133 +21,38 @@ module MailRoom
|
|
31
21
|
@running
|
32
22
|
end
|
33
23
|
|
34
|
-
# is the connection logged in?
|
35
|
-
# @return [Boolean]
|
36
|
-
def logged_in?
|
37
|
-
@logged_in
|
38
|
-
end
|
39
|
-
|
40
|
-
# is the connection blocked idling?
|
41
|
-
# @return [Boolean]
|
42
|
-
def idling?
|
43
|
-
@idling
|
44
|
-
end
|
45
|
-
|
46
|
-
# is the imap connection closed?
|
47
|
-
# @return [Boolean]
|
48
|
-
def disconnected?
|
49
|
-
@imap.disconnected?
|
50
|
-
end
|
51
|
-
|
52
|
-
# is the connection ready to idle?
|
53
|
-
# @return [Boolean]
|
54
|
-
def ready_to_idle?
|
55
|
-
logged_in? && !idling?
|
56
|
-
end
|
57
|
-
|
58
|
-
# is the response for a new message?
|
59
|
-
# @param response [Net::IMAP::TaggedResponse] the imap response from idle
|
60
|
-
# @return [Boolean]
|
61
|
-
def message_exists?(response)
|
62
|
-
response.respond_to?(:name) && response.name == 'EXISTS'
|
63
|
-
end
|
64
|
-
|
65
|
-
# log in and set the mailbox
|
66
|
-
def setup
|
67
|
-
reset
|
68
|
-
start_tls
|
69
|
-
log_in
|
70
|
-
set_mailbox
|
71
|
-
end
|
72
|
-
|
73
|
-
# clear disconnected imap
|
74
|
-
# reset imap state
|
75
|
-
def reset
|
76
|
-
@imap = nil
|
77
|
-
@logged_in = false
|
78
|
-
@idling = false
|
79
|
-
end
|
80
|
-
|
81
|
-
# start a TLS session
|
82
|
-
def start_tls
|
83
|
-
imap.starttls if @mailbox.start_tls
|
84
|
-
end
|
85
|
-
|
86
|
-
# send the imap login command to google
|
87
|
-
def log_in
|
88
|
-
imap.login(@mailbox.email, @mailbox.password)
|
89
|
-
@logged_in = true
|
90
|
-
end
|
91
|
-
|
92
|
-
# select the mailbox name we want to use
|
93
|
-
def set_mailbox
|
94
|
-
imap.select(@mailbox.name) if logged_in?
|
95
|
-
end
|
96
|
-
|
97
|
-
# maintain an imap idle connection
|
98
|
-
def idle
|
99
|
-
return unless ready_to_idle?
|
100
|
-
|
101
|
-
@idling = true
|
102
|
-
|
103
|
-
imap.idle(@mailbox.idle_timeout, &idle_handler)
|
104
|
-
ensure
|
105
|
-
@idling = false
|
106
|
-
end
|
107
|
-
|
108
|
-
# trigger the idle to finish and wait for the thread to finish
|
109
|
-
def stop_idling
|
110
|
-
return unless idling?
|
111
|
-
|
112
|
-
imap.idle_done
|
113
|
-
|
114
|
-
idling_thread.join
|
115
|
-
self.idling_thread = nil
|
116
|
-
end
|
117
|
-
|
118
24
|
# run the mailbox watcher
|
119
25
|
def run
|
120
|
-
setup
|
121
|
-
|
122
26
|
@running = true
|
123
27
|
|
124
|
-
|
125
|
-
|
28
|
+
connection.on_new_message do |message|
|
29
|
+
@mailbox.deliver(message)
|
30
|
+
end
|
126
31
|
|
127
|
-
self.
|
32
|
+
self.watching_thread = Thread.start do
|
128
33
|
while(running?) do
|
129
|
-
|
130
|
-
# block for idle_timeout until we stop idling
|
131
|
-
idle
|
132
|
-
|
133
|
-
# when new messages are ready
|
134
|
-
process_mailbox
|
135
|
-
rescue Net::IMAP::Error, IOError => e
|
136
|
-
# we've been disconnected, so re-setup
|
137
|
-
setup
|
138
|
-
end
|
34
|
+
connection.wait
|
139
35
|
end
|
140
36
|
end
|
141
37
|
|
142
|
-
|
38
|
+
watching_thread.abort_on_exception = true
|
143
39
|
end
|
144
40
|
|
145
|
-
# stop running
|
41
|
+
# stop running, cleanup connection
|
146
42
|
def quit
|
147
43
|
@running = false
|
148
|
-
stop_idling
|
149
|
-
# disconnect
|
150
|
-
end
|
151
44
|
|
152
|
-
|
153
|
-
|
154
|
-
|
45
|
+
if @connection
|
46
|
+
@connection.quit
|
47
|
+
@connection = nil
|
48
|
+
end
|
49
|
+
|
50
|
+
watching_thread.join
|
155
51
|
end
|
156
52
|
|
157
53
|
private
|
158
|
-
|
159
|
-
|
160
|
-
lambda {|response| imap.idle_done if message_exists?(response)}
|
54
|
+
def connection
|
55
|
+
@connection ||= Connection.new(@mailbox)
|
161
56
|
end
|
162
57
|
end
|
163
58
|
end
|
data/lib/mail_room/version.rb
CHANGED
data/spec/lib/cli_spec.rb
CHANGED
@@ -14,13 +14,13 @@ describe MailRoom::CLI do
|
|
14
14
|
end
|
15
15
|
|
16
16
|
it 'parses arguments into configuration' do
|
17
|
-
MailRoom::CLI.new(args).configuration.
|
18
|
-
MailRoom::Configuration.
|
17
|
+
expect(MailRoom::CLI.new(args).configuration).to eq(configuration)
|
18
|
+
expect(MailRoom::Configuration).to have_received(:new).with({:config_path => 'a path'})
|
19
19
|
end
|
20
20
|
|
21
21
|
it 'creates a new coordinator with configuration' do
|
22
|
-
MailRoom::CLI.new(args).coordinator.
|
23
|
-
MailRoom::Coordinator.
|
22
|
+
expect(MailRoom::CLI.new(args).coordinator).to eq(coordinator)
|
23
|
+
expect(MailRoom::Coordinator).to have_received(:new).with(configuration.mailboxes)
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
@@ -35,7 +35,7 @@ describe MailRoom::CLI do
|
|
35
35
|
it 'starts running the coordinator' do
|
36
36
|
cli.start
|
37
37
|
|
38
|
-
coordinator.
|
38
|
+
expect(coordinator).to have_received(:run)
|
39
39
|
end
|
40
40
|
end
|
41
41
|
end
|
@@ -9,7 +9,7 @@ describe MailRoom::Configuration do
|
|
9
9
|
|
10
10
|
configuration = MailRoom::Configuration.new(:config_path => config_path)
|
11
11
|
|
12
|
-
configuration.mailboxes.
|
12
|
+
expect(configuration.mailboxes).to eq(['mailbox1', 'mailbox2'])
|
13
13
|
end
|
14
14
|
|
15
15
|
it 'sets mailboxes to an empty set when config_path is missing' do
|
@@ -17,9 +17,9 @@ describe MailRoom::Configuration do
|
|
17
17
|
|
18
18
|
configuration = MailRoom::Configuration.new
|
19
19
|
|
20
|
-
configuration.mailboxes.
|
20
|
+
expect(configuration.mailboxes).to eq([])
|
21
21
|
|
22
|
-
MailRoom::Mailbox.
|
22
|
+
expect(MailRoom::Mailbox).to have_received(:new).never
|
23
23
|
end
|
24
24
|
end
|
25
25
|
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe MailRoom::Connection do
|
4
|
+
let(:imap) {stub}
|
5
|
+
let(:mailbox) {MailRoom::Mailbox.new(delete_after_delivery: true)}
|
6
|
+
|
7
|
+
before :each do
|
8
|
+
MailRoom::IMAP.stubs(:new).returns(imap)
|
9
|
+
end
|
10
|
+
|
11
|
+
context "with imap set up" do
|
12
|
+
let(:connection) {MailRoom::Connection.new(mailbox)}
|
13
|
+
|
14
|
+
before :each do
|
15
|
+
imap.stubs(:starttls)
|
16
|
+
imap.stubs(:login)
|
17
|
+
imap.stubs(:select)
|
18
|
+
end
|
19
|
+
|
20
|
+
it "is logged in" do
|
21
|
+
expect(connection.logged_in?).to eq(true)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "is not idling" do
|
25
|
+
expect(connection.idling?).to eq(false)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "is not disconnected" do
|
29
|
+
imap.stubs(:disconnected?).returns(false)
|
30
|
+
|
31
|
+
expect(connection.disconnected?).to eq(false)
|
32
|
+
end
|
33
|
+
|
34
|
+
it "is ready to idle" do
|
35
|
+
expect(connection.ready_to_idle?).to eq(true)
|
36
|
+
end
|
37
|
+
|
38
|
+
it "waits for a message to process" do
|
39
|
+
new_message = 'a message'
|
40
|
+
new_message.stubs(:seqno).returns(8)
|
41
|
+
|
42
|
+
connection.on_new_message do |message|
|
43
|
+
expect(message).to eq(new_message)
|
44
|
+
true
|
45
|
+
end
|
46
|
+
|
47
|
+
mailbox.stubs(:deliver?).returns(true)
|
48
|
+
|
49
|
+
imap.stubs(:idle)
|
50
|
+
imap.stubs(:uid_search).returns([]).then.returns([1])
|
51
|
+
imap.stubs(:uid_fetch).returns([new_message])
|
52
|
+
imap.stubs(:store)
|
53
|
+
|
54
|
+
connection.wait
|
55
|
+
|
56
|
+
expect(imap).to have_received(:idle)
|
57
|
+
expect(imap).to have_received(:uid_search).with(mailbox.search_command).twice
|
58
|
+
expect(imap).to have_received(:uid_fetch).with([1], "RFC822")
|
59
|
+
expect(mailbox).to have_received(:deliver?).with(1)
|
60
|
+
expect(imap).to have_received(:store).with(8, "+FLAGS", [Net::IMAP::DELETED])
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -7,15 +7,15 @@ describe MailRoom::Coordinator do
|
|
7
7
|
|
8
8
|
coordinator = MailRoom::Coordinator.new(['mailbox1', 'mailbox2'])
|
9
9
|
|
10
|
-
coordinator.watchers.
|
10
|
+
expect(coordinator.watchers).to eq(['watcher1', 'watcher2'])
|
11
11
|
|
12
|
-
MailRoom::MailboxWatcher.
|
13
|
-
MailRoom::MailboxWatcher.
|
12
|
+
expect(MailRoom::MailboxWatcher).to have_received(:new).with('mailbox1')
|
13
|
+
expect(MailRoom::MailboxWatcher).to have_received(:new).with('mailbox2')
|
14
14
|
end
|
15
15
|
|
16
16
|
it 'makes no watchers when mailboxes is empty' do
|
17
17
|
coordinator = MailRoom::Coordinator.new([])
|
18
|
-
coordinator.watchers.
|
18
|
+
expect(coordinator.watchers).to eq([])
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
@@ -28,8 +28,8 @@ describe MailRoom::Coordinator do
|
|
28
28
|
coordinator = MailRoom::Coordinator.new(['mailbox1'])
|
29
29
|
coordinator.stubs(:sleep_while_running)
|
30
30
|
coordinator.run
|
31
|
-
watcher.
|
32
|
-
watcher.
|
31
|
+
expect(watcher).to have_received(:run)
|
32
|
+
expect(watcher).to have_received(:quit)
|
33
33
|
end
|
34
34
|
|
35
35
|
it 'should go to sleep after running watchers' do
|
@@ -37,15 +37,15 @@ describe MailRoom::Coordinator do
|
|
37
37
|
coordinator.stubs(:running=)
|
38
38
|
coordinator.stubs(:running?).returns(false)
|
39
39
|
coordinator.run
|
40
|
-
coordinator.
|
41
|
-
coordinator.
|
40
|
+
expect(coordinator).to have_received(:running=).with(true)
|
41
|
+
expect(coordinator).to have_received(:running?)
|
42
42
|
end
|
43
43
|
|
44
44
|
it 'should set attribute running to true' do
|
45
45
|
coordinator = MailRoom::Coordinator.new([])
|
46
46
|
coordinator.stubs(:sleep_while_running)
|
47
47
|
coordinator.run
|
48
|
-
coordinator.running.
|
48
|
+
expect(coordinator.running).to eq(true)
|
49
49
|
end
|
50
50
|
end
|
51
51
|
|
@@ -55,7 +55,7 @@ describe MailRoom::Coordinator do
|
|
55
55
|
MailRoom::MailboxWatcher.stubs(:new).returns(watcher)
|
56
56
|
coordinator = MailRoom::Coordinator.new(['mailbox1'])
|
57
57
|
coordinator.quit
|
58
|
-
watcher.
|
58
|
+
expect(watcher).to have_received(:quit)
|
59
59
|
end
|
60
60
|
end
|
61
61
|
end
|
@@ -15,15 +15,15 @@ describe MailRoom::Delivery::LetterOpener do
|
|
15
15
|
end
|
16
16
|
|
17
17
|
it 'creates a new LetterOpener::DeliveryMethod' do
|
18
|
-
::LetterOpener::DeliveryMethod.
|
18
|
+
expect(::LetterOpener::DeliveryMethod).to have_received(:new).with(:location => '/tmp/somewhere')
|
19
19
|
end
|
20
20
|
|
21
21
|
it 'parses the message string with Mail' do
|
22
|
-
::Mail.
|
22
|
+
expect(::Mail).to have_received(:read_from_string).with('a message')
|
23
23
|
end
|
24
24
|
|
25
25
|
it 'delivers the mail message' do
|
26
|
-
delivery_method.
|
26
|
+
expect(delivery_method).to have_received(:deliver!).with(mail)
|
27
27
|
end
|
28
28
|
end
|
29
29
|
end
|
@@ -11,7 +11,7 @@ describe MailRoom::Delivery::Logger do
|
|
11
11
|
|
12
12
|
MailRoom::Delivery::Logger.new(mailbox)
|
13
13
|
|
14
|
-
::Logger.
|
14
|
+
expect(::Logger).to have_received(:new).with(STDOUT)
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
@@ -25,8 +25,8 @@ describe MailRoom::Delivery::Logger do
|
|
25
25
|
|
26
26
|
MailRoom::Delivery::Logger.new(mailbox)
|
27
27
|
|
28
|
-
File.
|
29
|
-
::Logger.
|
28
|
+
expect(File).to have_received(:open).with('/var/log/mail-room.log', 'a')
|
29
|
+
expect(::Logger).to have_received(:new).with(file)
|
30
30
|
end
|
31
31
|
end
|
32
32
|
end
|
@@ -40,7 +40,7 @@ describe MailRoom::Delivery::Logger do
|
|
40
40
|
|
41
41
|
MailRoom::Delivery::Logger.new(mailbox).deliver('a message')
|
42
42
|
|
43
|
-
logger.
|
43
|
+
expect(logger).to have_received(:info).with('a message')
|
44
44
|
end
|
45
45
|
end
|
46
46
|
end
|
@@ -21,11 +21,11 @@ describe MailRoom::Delivery::Postback do
|
|
21
21
|
|
22
22
|
MailRoom::Delivery::Postback.new(mailbox).deliver('a message')
|
23
23
|
|
24
|
-
connection.
|
25
|
-
connection.
|
24
|
+
expect(connection).to have_received(:token_auth).with('abcdefg')
|
25
|
+
expect(connection).to have_received(:post)
|
26
26
|
|
27
|
-
request.
|
28
|
-
request.
|
27
|
+
expect(request).to have_received(:url).with('http://localhost/inbox')
|
28
|
+
expect(request).to have_received(:body=).with('a message')
|
29
29
|
end
|
30
30
|
end
|
31
31
|
end
|
data/spec/lib/mailbox_spec.rb
CHANGED
@@ -12,7 +12,7 @@ describe MailRoom::Mailbox do
|
|
12
12
|
|
13
13
|
mailbox.deliver?(uid)
|
14
14
|
|
15
|
-
noop.
|
15
|
+
expect(noop).to have_received(:deliver?).with(uid)
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
@@ -26,7 +26,7 @@ describe MailRoom::Mailbox do
|
|
26
26
|
|
27
27
|
mailbox.deliver?(uid)
|
28
28
|
|
29
|
-
redis.
|
29
|
+
expect(redis).to have_received(:deliver?).with(uid)
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
@@ -38,7 +38,7 @@ describe MailRoom::Mailbox do
|
|
38
38
|
|
39
39
|
mailbox.deliver(stub(:attr => {'RFC822' => 'a message'}))
|
40
40
|
|
41
|
-
noop.
|
41
|
+
expect(noop).to have_received(:deliver).with('a message')
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
@@ -50,7 +50,7 @@ describe MailRoom::Mailbox do
|
|
50
50
|
|
51
51
|
mailbox.deliver(stub(:attr => {'RFC822' => 'a message'}))
|
52
52
|
|
53
|
-
logger.
|
53
|
+
expect(logger).to have_received(:deliver).with('a message')
|
54
54
|
end
|
55
55
|
end
|
56
56
|
|
@@ -62,7 +62,7 @@ describe MailRoom::Mailbox do
|
|
62
62
|
|
63
63
|
mailbox.deliver(stub(:attr => {'RFC822' => 'a message'}))
|
64
64
|
|
65
|
-
postback.
|
65
|
+
expect(postback).to have_received(:deliver).with('a message')
|
66
66
|
end
|
67
67
|
end
|
68
68
|
|
@@ -74,7 +74,7 @@ describe MailRoom::Mailbox do
|
|
74
74
|
|
75
75
|
mailbox.deliver(stub(:attr => {'RFC822' => 'a message'}))
|
76
76
|
|
77
|
-
letter_opener.
|
77
|
+
expect(letter_opener).to have_received(:deliver).with('a message')
|
78
78
|
end
|
79
79
|
end
|
80
80
|
|
@@ -86,7 +86,7 @@ describe MailRoom::Mailbox do
|
|
86
86
|
|
87
87
|
mailbox.deliver(stub(:attr => {'FLAGS' => [:Seen, :Recent]}))
|
88
88
|
|
89
|
-
noop.
|
89
|
+
expect(noop).to have_received(:deliver).never
|
90
90
|
end
|
91
91
|
end
|
92
92
|
|
@@ -6,245 +6,59 @@ describe MailRoom::MailboxWatcher do
|
|
6
6
|
describe '#running?' do
|
7
7
|
it 'is false by default' do
|
8
8
|
watcher = MailRoom::MailboxWatcher.new(mailbox)
|
9
|
-
watcher.running
|
9
|
+
expect(watcher.running?).to eq(false)
|
10
10
|
end
|
11
11
|
end
|
12
12
|
|
13
|
-
describe '#
|
14
|
-
it 'is false by default' do
|
15
|
-
watcher = MailRoom::MailboxWatcher.new(mailbox)
|
16
|
-
watcher.logged_in?.should eq(false)
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
describe '#idling?' do
|
21
|
-
it 'is false by default' do
|
22
|
-
watcher = MailRoom::MailboxWatcher.new(mailbox)
|
23
|
-
watcher.idling?.should eq(false)
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
describe '#imap' do
|
28
|
-
it 'builds a new Net::IMAP object' do
|
29
|
-
MailRoom::IMAP.stubs(:new).returns('imap')
|
30
|
-
|
31
|
-
MailRoom::MailboxWatcher.new(mailbox).imap.should eq('imap')
|
32
|
-
|
33
|
-
MailRoom::IMAP.should have_received(:new).with('imap.gmail.com', :port => 993, :ssl => true)
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
describe '#setup' do
|
13
|
+
describe '#run' do
|
38
14
|
let(:imap) {stub(:login => true, :select => true)}
|
39
|
-
|
40
|
-
let(:mailbox) {
|
41
|
-
MailRoom::Mailbox.new(:email => 'user1@gmail.com', :password => 'password', :name => 'inbox')
|
42
|
-
}
|
43
|
-
|
44
|
-
let(:watcher) {
|
45
|
-
MailRoom::MailboxWatcher.new(mailbox)
|
46
|
-
}
|
47
|
-
|
48
|
-
it 'logs in and sets the mailbox to watch' do
|
49
|
-
watcher.stubs(:imap).returns(imap)
|
50
|
-
|
51
|
-
watcher.setup
|
52
|
-
|
53
|
-
imap.should have_received(:login).with('user1@gmail.com', 'password')
|
54
|
-
watcher.logged_in?.should eq(true)
|
55
|
-
imap.should have_received(:select).with('inbox')
|
56
|
-
end
|
57
|
-
|
58
|
-
context 'with start_tls configured as true' do
|
59
|
-
before(:each) do
|
60
|
-
mailbox.start_tls = true
|
61
|
-
imap.stubs(:starttls)
|
62
|
-
watcher.stubs(:imap).returns(imap)
|
63
|
-
end
|
64
|
-
|
65
|
-
it 'sets up tls session on imap setup' do
|
66
|
-
watcher.setup
|
67
|
-
|
68
|
-
imap.should have_received(:starttls)
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
describe '#idle' do
|
74
|
-
let(:imap) {stub}
|
75
15
|
let(:watcher) {MailRoom::MailboxWatcher.new(mailbox)}
|
76
16
|
|
77
17
|
before :each do
|
78
|
-
|
79
|
-
end
|
80
|
-
|
81
|
-
it 'returns if not logged in' do
|
82
|
-
watcher.stubs(:logged_in?).returns(false)
|
83
|
-
|
84
|
-
watcher.idle
|
85
|
-
|
86
|
-
imap.should have_received(:idle).never
|
87
|
-
end
|
88
|
-
|
89
|
-
context "when logged in" do
|
90
|
-
before :each do
|
91
|
-
imap.stubs(:idle_done)
|
92
|
-
|
93
|
-
watcher.stubs(:logged_in?).returns(true)
|
94
|
-
end
|
95
|
-
|
96
|
-
it 'handles any response with a name of EXISTS and stops idling' do
|
97
|
-
response = stub(:name => 'EXISTS')
|
98
|
-
imap.stubs(:idle).yields(response)
|
99
|
-
|
100
|
-
watcher.idle
|
101
|
-
|
102
|
-
imap.should have_received(:idle)
|
103
|
-
imap.should have_received(:idle_done)
|
104
|
-
end
|
105
|
-
|
106
|
-
it 'does not finish idling when response is not EXISTS' do
|
107
|
-
response = stub(:name => 'DESTROY')
|
108
|
-
imap.stubs(:idle).yields(response)
|
109
|
-
|
110
|
-
watcher.idle
|
111
|
-
|
112
|
-
imap.should have_received(:idle)
|
113
|
-
imap.should have_received(:idle_done).never
|
114
|
-
end
|
18
|
+
Net::IMAP.stubs(:new).returns(imap) # prevent connection
|
115
19
|
end
|
116
|
-
end
|
117
20
|
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
21
|
+
it 'loops over wait while running' do
|
22
|
+
connection = MailRoom::Connection.new(mailbox)
|
23
|
+
connection.stubs(:on_new_message)
|
24
|
+
connection.stubs(:wait)
|
122
25
|
|
123
|
-
|
124
|
-
MailRoom::MailboxHandler.stubs(:new).returns(stub(:process))
|
125
|
-
watcher.stubs(:imap).returns(imap)
|
26
|
+
MailRoom::Connection.stubs(:new).returns(connection)
|
126
27
|
|
127
|
-
watcher.
|
128
|
-
|
129
|
-
MailRoom::MailboxHandler.should have_received(:new).with(mailbox, imap)
|
130
|
-
end
|
28
|
+
watcher.stubs(:running?).returns(true).then.returns(false)
|
131
29
|
|
132
|
-
|
133
|
-
|
134
|
-
watcher.stubs(:handler).returns(handler)
|
135
|
-
|
136
|
-
watcher.process_mailbox
|
137
|
-
|
138
|
-
handler.should have_received(:process)
|
139
|
-
end
|
140
|
-
end
|
141
|
-
|
142
|
-
describe '#stop_idling' do
|
143
|
-
let(:imap) {stub}
|
144
|
-
let(:idling_thread) {stub(:abort_on_exception=)}
|
145
|
-
let(:watcher) {MailRoom::MailboxWatcher.new(nil)}
|
146
|
-
|
147
|
-
before :each do
|
148
|
-
watcher.stubs(:imap).returns(imap)
|
149
|
-
watcher.stubs(:idling_thread).returns(idling_thread)
|
150
|
-
end
|
151
|
-
|
152
|
-
it "returns unless imap is idling" do
|
153
|
-
imap.stubs(:idle_done)
|
154
|
-
idling_thread.stubs(:join)
|
155
|
-
watcher.stubs(:idling?).returns(false)
|
156
|
-
|
157
|
-
watcher.stop_idling
|
158
|
-
|
159
|
-
imap.should have_received(:idle_done).never
|
160
|
-
idling_thread.should have_received(:join).never
|
161
|
-
end
|
30
|
+
watcher.run
|
31
|
+
watcher.watching_thread.join # wait for finishing run
|
162
32
|
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
idling_thread.stubs(:join)
|
167
|
-
watcher.stubs(:idling?).returns(true)
|
168
|
-
end
|
169
|
-
|
170
|
-
it 'stops the idle' do
|
171
|
-
watcher.stop_idling
|
172
|
-
imap.should have_received(:idle_done)
|
173
|
-
end
|
174
|
-
|
175
|
-
it 'waits on the idling_thread to finish' do
|
176
|
-
watcher.stop_idling
|
177
|
-
idling_thread.should have_received(:join)
|
178
|
-
end
|
33
|
+
expect(watcher).to have_received(:running?).times(2)
|
34
|
+
expect(connection).to have_received(:wait).once
|
35
|
+
expect(connection).to have_received(:on_new_message).once
|
179
36
|
end
|
180
37
|
end
|
181
38
|
|
182
|
-
describe '#
|
39
|
+
describe '#quit' do
|
40
|
+
let(:imap) {stub(:login => true, :select => true)}
|
183
41
|
let(:watcher) {MailRoom::MailboxWatcher.new(mailbox)}
|
184
42
|
|
185
43
|
before :each do
|
186
|
-
Net::IMAP.stubs(:new).returns(
|
187
|
-
Thread.stubs(:start).yields.returns(stub(:abort_on_exception=))
|
188
|
-
watcher.stubs(:setup)
|
189
|
-
watcher.handler.stubs(:process)
|
190
|
-
end
|
191
|
-
|
192
|
-
it 'sets up' do
|
193
|
-
watcher.stubs(:running?).returns(false)
|
194
|
-
|
195
|
-
watcher.run
|
196
|
-
|
197
|
-
watcher.should have_received(:setup)
|
198
|
-
end
|
199
|
-
|
200
|
-
it 'starts a thread for idling' do
|
201
|
-
watcher.stubs(:running?).returns(false)
|
202
|
-
|
203
|
-
watcher.run
|
204
|
-
|
205
|
-
Thread.should have_received(:start)
|
206
|
-
end
|
207
|
-
|
208
|
-
it 'loops while running' do
|
209
|
-
watcher.stubs(:running?).returns(true, false)
|
210
|
-
|
211
|
-
watcher.stubs(:idle)
|
212
|
-
|
213
|
-
watcher.run
|
214
|
-
|
215
|
-
watcher.should have_received(:running?).times(2)
|
216
|
-
end
|
217
|
-
|
218
|
-
it 'idles' do
|
219
|
-
watcher.stubs(:running?).returns(true, false)
|
220
|
-
|
221
|
-
watcher.stubs(:idle)
|
222
|
-
|
223
|
-
watcher.run
|
224
|
-
|
225
|
-
watcher.should have_received(:idle).once
|
44
|
+
Net::IMAP.stubs(:new).returns(imap) # prevent connection
|
226
45
|
end
|
227
46
|
|
228
|
-
it '
|
229
|
-
|
47
|
+
it 'closes and waits for the connection' do
|
48
|
+
connection = MailRoom::Connection.new(mailbox)
|
49
|
+
connection.stubs(:wait)
|
50
|
+
connection.stubs(:quit)
|
230
51
|
|
231
|
-
|
52
|
+
MailRoom::Connection.stubs(:new).returns(connection)
|
232
53
|
|
233
54
|
watcher.run
|
234
55
|
|
235
|
-
watcher.
|
236
|
-
end
|
237
|
-
end
|
238
|
-
|
239
|
-
describe '#quit' do
|
240
|
-
let(:watcher) {MailRoom::MailboxWatcher.new(mailbox)}
|
241
|
-
|
242
|
-
it 'stops idling' do
|
243
|
-
watcher.stubs(:stop_idling)
|
56
|
+
expect(watcher.running?).to eq(true)
|
244
57
|
|
245
58
|
watcher.quit
|
246
59
|
|
247
|
-
|
60
|
+
expect(connection).to have_received(:quit)
|
61
|
+
expect(watcher.running?).to eq(false)
|
248
62
|
end
|
249
63
|
end
|
250
64
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -12,7 +12,6 @@ require File.expand_path('../../lib/mail_room', __FILE__)
|
|
12
12
|
|
13
13
|
RSpec.configure do |config|
|
14
14
|
config.mock_with :mocha
|
15
|
-
config.treat_symbols_as_metadata_keys_with_true_values = true
|
16
15
|
config.run_all_when_everything_filtered = true
|
17
16
|
config.filter_run :focus
|
18
17
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mail_room
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tony Pitale
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-06-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -203,6 +203,7 @@ files:
|
|
203
203
|
- lib/mail_room/backports/imap.rb
|
204
204
|
- lib/mail_room/cli.rb
|
205
205
|
- lib/mail_room/configuration.rb
|
206
|
+
- lib/mail_room/connection.rb
|
206
207
|
- lib/mail_room/coordinator.rb
|
207
208
|
- lib/mail_room/delivery.rb
|
208
209
|
- lib/mail_room/delivery/letter_opener.rb
|
@@ -212,7 +213,6 @@ files:
|
|
212
213
|
- lib/mail_room/delivery/que.rb
|
213
214
|
- lib/mail_room/delivery/sidekiq.rb
|
214
215
|
- lib/mail_room/mailbox.rb
|
215
|
-
- lib/mail_room/mailbox_handler.rb
|
216
216
|
- lib/mail_room/mailbox_watcher.rb
|
217
217
|
- lib/mail_room/version.rb
|
218
218
|
- mail_room.gemspec
|
@@ -220,12 +220,12 @@ files:
|
|
220
220
|
- spec/lib/arbitration/redis_spec.rb
|
221
221
|
- spec/lib/cli_spec.rb
|
222
222
|
- spec/lib/configuration_spec.rb
|
223
|
+
- spec/lib/connection_spec.rb
|
223
224
|
- spec/lib/coordinator_spec.rb
|
224
225
|
- spec/lib/delivery/letter_opener_spec.rb
|
225
226
|
- spec/lib/delivery/logger_spec.rb
|
226
227
|
- spec/lib/delivery/postback_spec.rb
|
227
228
|
- spec/lib/delivery/que_spec.rb
|
228
|
-
- spec/lib/mailbox_handler_spec.rb
|
229
229
|
- spec/lib/mailbox_spec.rb
|
230
230
|
- spec/lib/mailbox_watcher_spec.rb
|
231
231
|
- spec/spec_helper.rb
|
@@ -258,12 +258,12 @@ test_files:
|
|
258
258
|
- spec/lib/arbitration/redis_spec.rb
|
259
259
|
- spec/lib/cli_spec.rb
|
260
260
|
- spec/lib/configuration_spec.rb
|
261
|
+
- spec/lib/connection_spec.rb
|
261
262
|
- spec/lib/coordinator_spec.rb
|
262
263
|
- spec/lib/delivery/letter_opener_spec.rb
|
263
264
|
- spec/lib/delivery/logger_spec.rb
|
264
265
|
- spec/lib/delivery/postback_spec.rb
|
265
266
|
- spec/lib/delivery/que_spec.rb
|
266
|
-
- spec/lib/mailbox_handler_spec.rb
|
267
267
|
- spec/lib/mailbox_spec.rb
|
268
268
|
- spec/lib/mailbox_watcher_spec.rb
|
269
269
|
- spec/spec_helper.rb
|
@@ -1,59 +0,0 @@
|
|
1
|
-
module MailRoom
|
2
|
-
# Fetches new email messages for delivery
|
3
|
-
# @author Tony Pitale
|
4
|
-
class MailboxHandler
|
5
|
-
# build a handler for this mailbox and our imap connection
|
6
|
-
# @param mailbox [MailRoom::Mailbox] the mailbox configuration
|
7
|
-
# @param imap [Net::IMAP::Connection] the open connection to gmail
|
8
|
-
def initialize(mailbox, imap)
|
9
|
-
@mailbox = mailbox
|
10
|
-
@imap = imap
|
11
|
-
end
|
12
|
-
|
13
|
-
# deliver each of the new messages
|
14
|
-
def process
|
15
|
-
# return if idling? || !running?
|
16
|
-
|
17
|
-
new_messages.each do |message|
|
18
|
-
# loop over delivery methods and deliver each
|
19
|
-
delivered = @mailbox.deliver(message)
|
20
|
-
|
21
|
-
if delivered && @mailbox.delete_after_delivery
|
22
|
-
@imap.store(message.seqno, "+FLAGS", [Net::IMAP::DELETED])
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
@imap.expunge if @mailbox.delete_after_delivery
|
27
|
-
end
|
28
|
-
|
29
|
-
private
|
30
|
-
# @private
|
31
|
-
# fetch all messages for the new message ids
|
32
|
-
def new_messages
|
33
|
-
# Both of these calls may results in
|
34
|
-
# imap raising an EOFError, we handle
|
35
|
-
# this exception in the watcher
|
36
|
-
messages_for_ids(new_message_ids)
|
37
|
-
end
|
38
|
-
|
39
|
-
# TODO: label messages?
|
40
|
-
# @imap.store(id, "+X-GM-LABELS", [label])
|
41
|
-
|
42
|
-
# @private
|
43
|
-
# search for all new (unseen) message ids
|
44
|
-
# @return [Array<Integer>] message ids
|
45
|
-
def new_message_ids
|
46
|
-
@imap.uid_search(@mailbox.search_command).select { |uid| @mailbox.deliver?(uid) }
|
47
|
-
end
|
48
|
-
|
49
|
-
# @private
|
50
|
-
# fetch the email for all given ids in RFC822 format
|
51
|
-
# @param ids [Array<Integer>] list of message ids
|
52
|
-
# @return [Array<Net::IMAP::FetchData>] the net/imap messages for the given ids
|
53
|
-
def messages_for_ids(uids)
|
54
|
-
return [] if uids.empty?
|
55
|
-
|
56
|
-
@imap.uid_fetch(uids, "RFC822")
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
@@ -1,57 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe MailRoom::MailboxHandler do
|
4
|
-
describe 'process mailbox' do
|
5
|
-
let(:imap) {stub}
|
6
|
-
let(:mailbox) {MailRoom::Mailbox.new}
|
7
|
-
|
8
|
-
it 'fetches and delivers all new messages from ids' do
|
9
|
-
imap.stubs(:uid_search).returns([1,2])
|
10
|
-
message1 = stub(:attr => {'RFC822' => 'message1'})
|
11
|
-
message2 = stub(:attr => {'RFC822' => 'message2'})
|
12
|
-
imap.stubs(:uid_fetch).returns([message1, message2])
|
13
|
-
mailbox.stubs(:deliver)
|
14
|
-
|
15
|
-
handler = MailRoom::MailboxHandler.new(mailbox, imap)
|
16
|
-
handler.process
|
17
|
-
|
18
|
-
imap.should have_received(:uid_search).with('UNSEEN')
|
19
|
-
imap.should have_received(:uid_fetch).with([1,2], 'RFC822')
|
20
|
-
mailbox.should have_received(:deliver).with(message1)
|
21
|
-
mailbox.should have_received(:deliver).with(message2)
|
22
|
-
end
|
23
|
-
|
24
|
-
it "fetches and delivers all new messages from ids that haven't been processed yet" do
|
25
|
-
imap.stubs(:uid_search).returns([1,2])
|
26
|
-
message1 = stub(:attr => {'RFC822' => 'message1'})
|
27
|
-
message2 = stub(:attr => {'RFC822' => 'message2'})
|
28
|
-
imap.stubs(:uid_fetch).returns([message2])
|
29
|
-
mailbox.stubs(:deliver)
|
30
|
-
mailbox.stubs(:deliver?).with(1).returns(false)
|
31
|
-
mailbox.stubs(:deliver?).with(2).returns(true)
|
32
|
-
|
33
|
-
handler = MailRoom::MailboxHandler.new(mailbox, imap)
|
34
|
-
handler.process
|
35
|
-
|
36
|
-
imap.should have_received(:uid_search).with('UNSEEN')
|
37
|
-
imap.should have_received(:uid_fetch).with([2], 'RFC822')
|
38
|
-
|
39
|
-
mailbox.should have_received(:deliver).with(message1).never
|
40
|
-
mailbox.should have_received(:deliver).with(message2)
|
41
|
-
end
|
42
|
-
|
43
|
-
it 'returns no messages if there are no ids' do
|
44
|
-
imap.stubs(:uid_search).returns([])
|
45
|
-
imap.stubs(:uid_fetch)
|
46
|
-
mailbox.search_command = 'NEW'
|
47
|
-
mailbox.stubs(:deliver)
|
48
|
-
|
49
|
-
handler = MailRoom::MailboxHandler.new(mailbox, imap)
|
50
|
-
handler.process
|
51
|
-
|
52
|
-
imap.should have_received(:uid_search).with('NEW')
|
53
|
-
imap.should have_received(:uid_fetch).never
|
54
|
-
mailbox.should have_received(:deliver).never
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|