imap-backup 5.2.0 → 6.0.0.rc2
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/README.md +9 -2
- data/docs/development.md +10 -4
- data/lib/cli_coverage.rb +1 -1
- data/lib/imap/backup/account/connection.rb +7 -11
- data/lib/imap/backup/account.rb +31 -11
- data/lib/imap/backup/cli/folders.rb +3 -3
- data/lib/imap/backup/cli/migrate.rb +3 -3
- data/lib/imap/backup/cli/utils.rb +2 -2
- data/lib/imap/backup/configuration.rb +1 -11
- data/lib/imap/backup/downloader.rb +13 -9
- data/lib/imap/backup/serializer/directory.rb +37 -0
- data/lib/imap/backup/serializer/imap.rb +120 -0
- data/lib/imap/backup/serializer/mbox.rb +23 -94
- data/lib/imap/backup/serializer/mbox_enumerator.rb +2 -0
- data/lib/imap/backup/serializer.rb +180 -3
- data/lib/imap/backup/setup/account.rb +52 -29
- data/lib/imap/backup/setup/helpers.rb +1 -1
- data/lib/imap/backup/thunderbird/mailbox_exporter.rb +1 -1
- data/lib/imap/backup/version.rb +3 -3
- data/lib/imap/backup.rb +0 -1
- data/spec/features/backup_spec.rb +8 -16
- data/spec/features/support/aruba.rb +4 -3
- data/spec/unit/imap/backup/account/connection_spec.rb +36 -8
- data/spec/unit/imap/backup/account/folder_spec.rb +10 -0
- data/spec/unit/imap/backup/account_spec.rb +246 -0
- data/spec/unit/imap/backup/cli/accounts_spec.rb +12 -1
- data/spec/unit/imap/backup/cli/backup_spec.rb +19 -0
- data/spec/unit/imap/backup/cli/folders_spec.rb +39 -0
- data/spec/unit/imap/backup/cli/local_spec.rb +26 -7
- data/spec/unit/imap/backup/cli/migrate_spec.rb +80 -0
- data/spec/unit/imap/backup/cli/restore_spec.rb +67 -0
- data/spec/unit/imap/backup/cli/setup_spec.rb +17 -0
- data/spec/unit/imap/backup/cli/utils_spec.rb +68 -5
- data/spec/unit/imap/backup/cli_spec.rb +93 -0
- data/spec/unit/imap/backup/client/apple_mail_spec.rb +9 -0
- data/spec/unit/imap/backup/configuration_spec.rb +2 -2
- data/spec/unit/imap/backup/downloader_spec.rb +59 -7
- data/spec/unit/imap/backup/migrator_spec.rb +1 -1
- data/spec/unit/imap/backup/sanitizer_spec.rb +42 -0
- data/spec/unit/imap/backup/serializer/directory_spec.rb +37 -0
- data/spec/unit/imap/backup/serializer/imap_spec.rb +218 -0
- data/spec/unit/imap/backup/serializer/mbox_spec.rb +62 -183
- data/spec/unit/imap/backup/serializer_spec.rb +296 -0
- data/spec/unit/imap/backup/setup/account_spec.rb +120 -25
- data/spec/unit/imap/backup/setup/helpers_spec.rb +15 -0
- data/spec/unit/imap/backup/thunderbird/mailbox_exporter_spec.rb +116 -0
- data/spec/unit/imap/backup/uploader_spec.rb +1 -1
- data/spec/unit/retry_on_error_spec.rb +34 -0
- metadata +36 -7
- data/lib/imap/backup/serializer/mbox_store.rb +0 -217
- data/spec/unit/imap/backup/serializer/mbox_store_spec.rb +0 -329
@@ -1,222 +1,101 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
end
|
16
|
-
let(:imap_folder) { "folder" }
|
17
|
-
let(:permissions) { 0o700 }
|
18
|
-
let(:dir_exists) { true }
|
19
|
-
let(:existing_uid_validity) { nil }
|
20
|
-
|
21
|
-
before do
|
22
|
-
allow(Imap::Backup::Utils).to receive(:make_folder)
|
23
|
-
allow(Imap::Backup::Utils).to receive(:mode) { permissions }
|
24
|
-
allow(Imap::Backup::Utils).to receive(:check_permissions) { true }
|
25
|
-
allow(File).to receive(:directory?) { dir_exists }
|
26
|
-
allow(FileUtils).to receive(:chmod)
|
27
|
-
allow(Imap::Backup::Serializer::MboxStore).to receive(:new) { store }
|
28
|
-
end
|
29
|
-
|
30
|
-
describe "folder path" do
|
31
|
-
context "when it has multiple elements" do
|
32
|
-
let(:imap_folder) { "folder/path" }
|
33
|
-
|
34
|
-
context "when the containing directory is missing" do
|
35
|
-
let(:dir_exists) { false }
|
36
|
-
|
37
|
-
it "is created" do
|
38
|
-
expect(Imap::Backup::Utils).to receive(:make_folder).
|
39
|
-
with(base_path, File.dirname(imap_folder), 0o700)
|
40
|
-
|
41
|
-
subject.uids
|
42
|
-
end
|
43
|
-
end
|
1
|
+
module Imap::Backup
|
2
|
+
describe Serializer::Mbox do
|
3
|
+
subject { described_class.new(folder_path) }
|
4
|
+
|
5
|
+
let(:folder_path) { "folder_path" }
|
6
|
+
let(:pathname) { "folder_path.mbox" }
|
7
|
+
let(:exists) { true }
|
8
|
+
let(:file) { instance_double(File, truncate: nil, write: nil) }
|
9
|
+
|
10
|
+
before do
|
11
|
+
allow(File).to receive(:exist?).and_call_original
|
12
|
+
allow(File).to receive(:exist?).with(pathname) { exists }
|
13
|
+
allow(File).to receive(:open).with(pathname, "ab").and_yield(file)
|
14
|
+
allow(File).to receive(:read).with(pathname) { existing.to_json }
|
44
15
|
end
|
45
16
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
it "corrects them" do
|
50
|
-
path = File.expand_path(File.join(base_path, File.dirname(imap_folder)))
|
51
|
-
expect(FileUtils).to receive(:chmod).with(0o700, path)
|
17
|
+
describe "#append" do
|
18
|
+
it "appends the message" do
|
19
|
+
subject.append("message")
|
52
20
|
|
53
|
-
|
21
|
+
expect(file).to have_received(:write).with("message")
|
54
22
|
end
|
55
23
|
end
|
56
24
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
25
|
+
describe "#exist?" do
|
26
|
+
context "when the mailbox exists" do
|
27
|
+
it "is true" do
|
28
|
+
expect(subject.exist?).to be true
|
29
|
+
end
|
62
30
|
end
|
63
|
-
end
|
64
31
|
|
65
|
-
|
66
|
-
|
67
|
-
expect(Imap::Backup::Utils).to_not receive(:make_folder).
|
68
|
-
with(base_path, File.dirname(imap_folder), 0o700)
|
32
|
+
context "when the mailbox doesn't exist" do
|
33
|
+
let(:exists) { false }
|
69
34
|
|
70
|
-
|
35
|
+
it "is false" do
|
36
|
+
expect(subject.exist?).to be false
|
37
|
+
end
|
71
38
|
end
|
72
39
|
end
|
73
|
-
end
|
74
|
-
|
75
|
-
describe "#apply_uid_validity" do
|
76
|
-
context "when the existing uid validity is unset" do
|
77
|
-
it "sets uid validity" do
|
78
|
-
expect(store).to receive(:uid_validity=).with("aaa")
|
79
40
|
|
80
|
-
|
81
|
-
|
41
|
+
describe "#length" do
|
42
|
+
let(:stat) { instance_double(File::Stat, size: 99) }
|
82
43
|
|
83
|
-
|
84
|
-
expect(store).to_not receive(:rename)
|
44
|
+
before { allow(File).to receive(:stat) { stat } }
|
85
45
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
it "returns nil" do
|
90
|
-
expect(subject.apply_uid_validity("aaa")).to be_nil
|
46
|
+
it "returns the length of the mailbox file" do
|
47
|
+
expect(subject.length).to eq(99)
|
91
48
|
end
|
92
49
|
end
|
93
50
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
it "does not set uid validity" do
|
98
|
-
expect(store).to_not receive(:uid_validity=)
|
99
|
-
|
100
|
-
subject.apply_uid_validity("aaa")
|
101
|
-
end
|
102
|
-
|
103
|
-
it "does not rename the store" do
|
104
|
-
expect(store).to_not receive(:rename)
|
105
|
-
|
106
|
-
subject.apply_uid_validity("aaa")
|
107
|
-
end
|
108
|
-
|
109
|
-
it "returns nil" do
|
110
|
-
expect(subject.apply_uid_validity("aaa")).to be_nil
|
51
|
+
describe "#pathname" do
|
52
|
+
it "is the folder_path plus .mbox" do
|
53
|
+
expect(subject.pathname).to eq("folder_path.mbox")
|
111
54
|
end
|
112
55
|
end
|
113
56
|
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
instance_double(Imap::Backup::Serializer::MboxStore)
|
118
|
-
end
|
119
|
-
let(:exists) { false }
|
120
|
-
|
121
|
-
before do
|
122
|
-
allow(Imap::Backup::Serializer::MboxStore).
|
123
|
-
to receive(:new).with(anything, /bbb/) { existing_store }
|
124
|
-
allow(existing_store).to receive(:exist?).and_return(exists, false)
|
125
|
-
end
|
126
|
-
|
127
|
-
it "sets uid validity" do
|
128
|
-
expect(store).to receive(:uid_validity=).with("aaa")
|
57
|
+
describe "#rename" do
|
58
|
+
context "when the mailbox exists" do
|
59
|
+
let(:exists) { true }
|
129
60
|
|
130
|
-
|
131
|
-
|
61
|
+
before do
|
62
|
+
allow(File).to receive(:rename)
|
132
63
|
|
133
|
-
|
134
|
-
|
135
|
-
expect(store).to receive(:rename).with("folder-bbb")
|
64
|
+
subject.rename("new_name")
|
65
|
+
end
|
136
66
|
|
137
|
-
|
67
|
+
it "renames the mailbox" do
|
68
|
+
expect(File).to have_received(:rename)
|
138
69
|
end
|
139
70
|
|
140
|
-
it "
|
141
|
-
expect(subject.
|
71
|
+
it "sets the folder_path" do
|
72
|
+
expect(subject.folder_path).to eq("new_name")
|
142
73
|
end
|
143
74
|
end
|
144
75
|
|
145
|
-
context "when
|
146
|
-
let(:exists) {
|
147
|
-
|
148
|
-
it "renames the store, adding the existing uid validity and a digit" do
|
149
|
-
expect(store).to receive(:rename).with("folder-bbb-1")
|
76
|
+
context "when the mailbox doesn't exist" do
|
77
|
+
let(:exists) { false }
|
150
78
|
|
151
|
-
|
152
|
-
|
79
|
+
it "sets the folder_path" do
|
80
|
+
subject.rename("new_name")
|
153
81
|
|
154
|
-
|
155
|
-
expect(subject.apply_uid_validity("aaa")).to eq("folder-bbb-1")
|
82
|
+
expect(subject.folder_path).to eq("new_name")
|
156
83
|
end
|
157
84
|
end
|
158
85
|
end
|
159
|
-
end
|
160
|
-
|
161
|
-
describe "#force_uid_validity" do
|
162
|
-
it "sets the uid_validity" do
|
163
|
-
expect(store).to receive(:uid_validity=).with("66")
|
164
|
-
|
165
|
-
subject.force_uid_validity("66")
|
166
|
-
end
|
167
|
-
end
|
168
|
-
|
169
|
-
describe "#uids" do
|
170
|
-
it "calls the store" do
|
171
|
-
expect(store).to receive(:uids)
|
172
|
-
|
173
|
-
subject.uids
|
174
|
-
end
|
175
|
-
end
|
176
|
-
|
177
|
-
describe "#load" do
|
178
|
-
before { allow(store).to receive(:load).with("66") { "xxx" } }
|
179
|
-
|
180
|
-
it "returns the value loaded by the store" do
|
181
|
-
expect(subject.load("66")).to eq("xxx")
|
182
|
-
end
|
183
|
-
end
|
184
|
-
|
185
|
-
describe "#each_message" do
|
186
|
-
it "calls the store" do
|
187
|
-
expect(store).to receive(:each_message).with([1])
|
188
86
|
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
expect(store).to receive(:add).with("foo", "bar")
|
196
|
-
|
197
|
-
subject.save("foo", "bar")
|
198
|
-
end
|
199
|
-
end
|
200
|
-
|
201
|
-
describe "#rename" do
|
202
|
-
it "calls the store" do
|
203
|
-
expect(store).to receive(:rename).with("foo")
|
204
|
-
|
205
|
-
subject.rename("foo")
|
206
|
-
end
|
207
|
-
|
208
|
-
it "updates the folder name" do
|
209
|
-
subject.rename("foo")
|
210
|
-
|
211
|
-
expect(subject.folder).to eq("foo")
|
212
|
-
end
|
213
|
-
end
|
87
|
+
describe "#rewind" do
|
88
|
+
before do
|
89
|
+
allow(File).to receive(:open).
|
90
|
+
with(pathname, File::RDWR | File::CREAT, 0o644).
|
91
|
+
and_yield(file)
|
92
|
+
end
|
214
93
|
|
215
|
-
|
216
|
-
|
217
|
-
expect(store).to receive(:update_uid).with("foo", "bar")
|
94
|
+
it "truncates the mailbox" do
|
95
|
+
subject.rewind(123)
|
218
96
|
|
219
|
-
|
97
|
+
expect(file).to have_received(:truncate).with(123)
|
98
|
+
end
|
220
99
|
end
|
221
100
|
end
|
222
101
|
end
|
@@ -0,0 +1,296 @@
|
|
1
|
+
module Imap::Backup
|
2
|
+
describe Serializer do
|
3
|
+
subject { described_class.new("path", "folder/sub") }
|
4
|
+
|
5
|
+
let(:directory) { instance_double(Serializer::Directory, ensure_exists: nil) }
|
6
|
+
let(:imap) do
|
7
|
+
instance_double(
|
8
|
+
Serializer::Imap,
|
9
|
+
exist?: true,
|
10
|
+
rename: nil,
|
11
|
+
uid_validity: existing_uid_validity,
|
12
|
+
"uid_validity=": nil
|
13
|
+
)
|
14
|
+
end
|
15
|
+
let(:mbox) do
|
16
|
+
instance_double(
|
17
|
+
Serializer::Mbox,
|
18
|
+
append: nil,
|
19
|
+
exist?: false,
|
20
|
+
length: 1,
|
21
|
+
pathname: "aaa",
|
22
|
+
rename: nil,
|
23
|
+
rewind: nil
|
24
|
+
)
|
25
|
+
end
|
26
|
+
let(:folder_path) { File.expand_path(File.join("path", "folder/sub")) }
|
27
|
+
let(:existing_uid_validity) { nil }
|
28
|
+
let(:enumerator) { instance_double(Serializer::MboxEnumerator) }
|
29
|
+
|
30
|
+
before do
|
31
|
+
allow(Serializer::Directory).to receive(:new) { directory }
|
32
|
+
allow(Serializer::Imap).to receive(:new).with(folder_path) { imap }
|
33
|
+
allow(Serializer::Mbox).to receive(:new) { mbox }
|
34
|
+
allow(Serializer::MboxEnumerator).to receive(:new) { enumerator }
|
35
|
+
end
|
36
|
+
|
37
|
+
describe "#apply_uid_validity" do
|
38
|
+
let(:imap_test) { instance_double(Serializer::Imap, exist?: imap_test_exists) }
|
39
|
+
let(:imap_test_exists) { false }
|
40
|
+
let(:test_folder_path) do
|
41
|
+
File.expand_path(File.join("path", "folder/sub-#{existing_uid_validity}"))
|
42
|
+
end
|
43
|
+
let(:result) { subject.apply_uid_validity("new") }
|
44
|
+
|
45
|
+
before do
|
46
|
+
allow(Serializer::Imap).to receive(:new).with(test_folder_path) { imap_test }
|
47
|
+
end
|
48
|
+
|
49
|
+
context "when there is no existing uid_validity" do
|
50
|
+
it "sets the metadata file's uid_validity" do
|
51
|
+
result
|
52
|
+
|
53
|
+
expect(imap).to have_received(:"uid_validity=").with("new")
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
context "when the new value is the same as the old value" do
|
58
|
+
let(:existing_uid_validity) { "new" }
|
59
|
+
|
60
|
+
it "does nothing" do
|
61
|
+
result
|
62
|
+
|
63
|
+
expect(imap).to_not have_received(:"uid_validity=")
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
context "when the new value is different from the old value" do
|
68
|
+
let(:existing_uid_validity) { "existing" }
|
69
|
+
|
70
|
+
it "renames the existing mailbox" do
|
71
|
+
result
|
72
|
+
|
73
|
+
expect(mbox).to have_received(:rename).with(test_folder_path)
|
74
|
+
end
|
75
|
+
|
76
|
+
it "renames the existing metadata file" do
|
77
|
+
result
|
78
|
+
|
79
|
+
expect(imap).to have_received(:rename).with(test_folder_path)
|
80
|
+
end
|
81
|
+
|
82
|
+
it "returns the new name for the old folder" do
|
83
|
+
expect(result).to eq("folder/sub-existing")
|
84
|
+
end
|
85
|
+
|
86
|
+
context "when the default rename is not possible" do
|
87
|
+
let(:imap_test_exists) { true }
|
88
|
+
let(:imap_test1) { instance_double(Serializer::Imap, exist?: false) }
|
89
|
+
let(:test_folder_path1) do
|
90
|
+
File.expand_path(File.join("path", "folder/sub-#{existing_uid_validity}-1"))
|
91
|
+
end
|
92
|
+
|
93
|
+
before do
|
94
|
+
allow(Serializer::Imap).to receive(:new).with(test_folder_path1) { imap_test1 }
|
95
|
+
end
|
96
|
+
|
97
|
+
it "renames the mailbox, appending a numeral" do
|
98
|
+
result
|
99
|
+
|
100
|
+
expect(mbox).to have_received(:rename).with(test_folder_path1)
|
101
|
+
end
|
102
|
+
|
103
|
+
it "renames the metadata file, appending a numeral" do
|
104
|
+
result
|
105
|
+
|
106
|
+
expect(imap).to have_received(:rename).with(test_folder_path1)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
describe "#force_uid_validity" do
|
113
|
+
it "sets the metadata file's uid_validity" do
|
114
|
+
subject.force_uid_validity("new")
|
115
|
+
|
116
|
+
expect(imap).to have_received(:"uid_validity=").with("new")
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
describe "#append" do
|
121
|
+
let(:existing_uid_validity) { "42" }
|
122
|
+
let(:mboxrd_message) do
|
123
|
+
instance_double(Email::Mboxrd::Message, to_serialized: "serialized")
|
124
|
+
end
|
125
|
+
let(:uid_found) { false }
|
126
|
+
let(:command) { subject.append(99, "Hi") }
|
127
|
+
|
128
|
+
before do
|
129
|
+
allow(imap).to receive(:include?) { uid_found }
|
130
|
+
allow(imap).to receive(:append)
|
131
|
+
allow(Email::Mboxrd::Message).to receive(:new) { mboxrd_message }
|
132
|
+
end
|
133
|
+
|
134
|
+
it "appends the message to the mailbox" do
|
135
|
+
command
|
136
|
+
|
137
|
+
expect(mbox).to have_received(:append).with("serialized")
|
138
|
+
end
|
139
|
+
|
140
|
+
it "appends the UID to the metadata" do
|
141
|
+
command
|
142
|
+
|
143
|
+
expect(imap).to have_received(:append).with(99)
|
144
|
+
end
|
145
|
+
|
146
|
+
context "when appending to the mailbox causes an error" do
|
147
|
+
before do
|
148
|
+
allow(mbox).to receive(:append).and_throw(RuntimeError, "Boom")
|
149
|
+
end
|
150
|
+
|
151
|
+
it "does not fail" do
|
152
|
+
command
|
153
|
+
end
|
154
|
+
|
155
|
+
it "leaves the metadata file unchanged" do
|
156
|
+
command
|
157
|
+
|
158
|
+
expect(imap).to_not have_received(:append)
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
context "when appending to the metadata file causes an error" do
|
163
|
+
before do
|
164
|
+
allow(imap).to receive(:append).and_throw(RuntimeError, "Boom")
|
165
|
+
end
|
166
|
+
|
167
|
+
it "does not fail" do
|
168
|
+
command
|
169
|
+
end
|
170
|
+
|
171
|
+
it "reset the mailbox to the previous position" do
|
172
|
+
command
|
173
|
+
|
174
|
+
expect(mbox).to have_received(:rewind)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
context "when the metadata uid_validity has not been set" do
|
179
|
+
let(:existing_uid_validity) { nil }
|
180
|
+
|
181
|
+
it "fails" do
|
182
|
+
expect { command }.to raise_error(RuntimeError, /without uid_validity/)
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
context "when the message has already been backed up" do
|
187
|
+
let(:uid_found) { true }
|
188
|
+
|
189
|
+
it "doesn't append to the mailbox file" do
|
190
|
+
command
|
191
|
+
|
192
|
+
expect(mbox).to_not have_received(:append)
|
193
|
+
end
|
194
|
+
|
195
|
+
it "doesn't append to the metadata file" do
|
196
|
+
command
|
197
|
+
|
198
|
+
expect(imap).to_not have_received(:append)
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
describe "#load" do
|
204
|
+
let(:uid) { 999 }
|
205
|
+
let(:imap_index) { 0 }
|
206
|
+
let(:result) { subject.load(uid) }
|
207
|
+
|
208
|
+
before do
|
209
|
+
allow(imap).to receive(:index).with(999) { imap_index }
|
210
|
+
allow(enumerator).to receive(:each) { ["message"].enum_for(:each) }
|
211
|
+
end
|
212
|
+
|
213
|
+
it "returns an Email::Mboxrd::Message" do
|
214
|
+
expect(result).to be_a(Email::Mboxrd::Message)
|
215
|
+
end
|
216
|
+
|
217
|
+
it "returns the message" do
|
218
|
+
expect(result.supplied_body).to eq("message")
|
219
|
+
end
|
220
|
+
|
221
|
+
context "when the message is not found" do
|
222
|
+
let(:imap_index) { nil }
|
223
|
+
|
224
|
+
it "returns nil" do
|
225
|
+
expect(result).to be nil
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
context "when the supplied UID is a string" do
|
230
|
+
let(:uid) { "999" }
|
231
|
+
|
232
|
+
it "works" do
|
233
|
+
expect(result).to be_a(Email::Mboxrd::Message)
|
234
|
+
end
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
describe "#load_nth" do
|
239
|
+
let(:imap_index) { 0 }
|
240
|
+
let(:result) { subject.load_nth(imap_index) }
|
241
|
+
|
242
|
+
before do
|
243
|
+
allow(enumerator).to receive(:each) { ["message"].enum_for(:each) }
|
244
|
+
end
|
245
|
+
|
246
|
+
it "returns an Email::Mboxrd::Message" do
|
247
|
+
expect(result).to be_a(Email::Mboxrd::Message)
|
248
|
+
end
|
249
|
+
|
250
|
+
it "returns the message" do
|
251
|
+
expect(result.supplied_body).to eq("message")
|
252
|
+
end
|
253
|
+
|
254
|
+
context "when the message is not found" do
|
255
|
+
let(:imap_index) { 1 }
|
256
|
+
|
257
|
+
it "returns nil" do
|
258
|
+
expect(result).to be nil
|
259
|
+
end
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
describe "#each_message" do
|
264
|
+
let(:good_uid) { 999 }
|
265
|
+
|
266
|
+
before do
|
267
|
+
allow(imap).to receive(:index) { nil }
|
268
|
+
allow(imap).to receive(:index).with(good_uid) { 0 }
|
269
|
+
allow(enumerator).to receive(:each) { ["message"].enum_for(:each) }
|
270
|
+
end
|
271
|
+
|
272
|
+
it "yields matching UIDs" do
|
273
|
+
expect { |b| subject.each_message([good_uid], &b) }.
|
274
|
+
to yield_successive_args([good_uid, anything])
|
275
|
+
end
|
276
|
+
|
277
|
+
it "yields matching messages" do
|
278
|
+
messages = subject.each_message([good_uid]).map { |_uid, message| message }
|
279
|
+
expect(messages[0].supplied_body).to eq("message")
|
280
|
+
end
|
281
|
+
|
282
|
+
context "with UIDs that are not present" do
|
283
|
+
it "skips them" do
|
284
|
+
expect { |b| subject.each_message([good_uid, 1234], &b) }.
|
285
|
+
to yield_successive_args([good_uid, anything])
|
286
|
+
end
|
287
|
+
end
|
288
|
+
|
289
|
+
context "when called without a block" do
|
290
|
+
it "returns an Enumerator" do
|
291
|
+
expect(subject.each_message([])).to be_a(Enumerator)
|
292
|
+
end
|
293
|
+
end
|
294
|
+
end
|
295
|
+
end
|
296
|
+
end
|