mail_room 0.7.0 → 0.8.0
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/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
|