imap-backup 4.0.1 → 4.0.5
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 -1
- data/docs/development.md +5 -12
- data/imap-backup.gemspec +1 -4
- data/lib/email/mboxrd/message.rb +6 -2
- data/lib/email/provider/apple_mail.rb +7 -0
- data/lib/email/provider/base.rb +8 -0
- data/lib/email/provider/fastmail.rb +7 -0
- data/lib/email/provider/gmail.rb +7 -0
- data/lib/email/provider/unknown.rb +11 -0
- data/lib/email/provider.rb +16 -26
- data/lib/imap/backup/account/connection.rb +19 -29
- data/lib/imap/backup/account/folder.rb +9 -10
- data/lib/imap/backup/account.rb +103 -0
- data/lib/imap/backup/cli/helpers.rb +14 -0
- data/lib/imap/backup/cli/local.rb +19 -25
- data/lib/imap/backup/cli/utils.rb +67 -10
- data/lib/imap/backup/client/apple_mail.rb +11 -0
- data/lib/imap/backup/client/default.rb +51 -0
- data/lib/imap/backup/configuration/account.rb +3 -1
- data/lib/imap/backup/configuration/connection_tester.rb +1 -1
- data/lib/imap/backup/configuration/store.rb +10 -5
- data/lib/imap/backup/downloader.rb +3 -4
- data/lib/imap/backup/serializer/mbox.rb +5 -0
- data/lib/imap/backup/serializer/mbox_store.rb +8 -8
- data/lib/imap/backup/thunderbird/mailbox_exporter.rb +58 -0
- data/lib/imap/backup/version.rb +1 -1
- data/lib/imap/backup.rb +1 -0
- data/lib/thunderbird/install.rb +16 -0
- data/lib/thunderbird/local_folder.rb +65 -0
- data/lib/thunderbird/profile.rb +30 -0
- data/lib/thunderbird/profiles.rb +71 -0
- data/lib/thunderbird/subdirectory.rb +96 -0
- data/lib/thunderbird/subdirectory_placeholder.rb +21 -0
- data/lib/thunderbird.rb +14 -0
- data/spec/features/restore_spec.rb +1 -1
- data/spec/features/support/email_server.rb +2 -2
- data/spec/unit/email/provider/apple_mail_spec.rb +7 -0
- data/spec/unit/email/provider/base_spec.rb +11 -0
- data/spec/unit/email/provider/fastmail_spec.rb +7 -0
- data/spec/unit/email/provider/gmail_spec.rb +7 -0
- data/spec/unit/email/provider_spec.rb +12 -25
- data/spec/unit/imap/backup/account/connection_spec.rb +26 -51
- data/spec/unit/imap/backup/account/folder_spec.rb +22 -22
- data/spec/unit/imap/backup/cli/local_spec.rb +70 -0
- data/spec/unit/imap/backup/cli/utils_spec.rb +50 -0
- data/spec/unit/imap/backup/client/default_spec.rb +22 -0
- data/spec/unit/imap/backup/configuration/connection_tester_spec.rb +3 -3
- data/spec/unit/imap/backup/configuration/store_spec.rb +25 -12
- data/spec/unit/imap/backup/downloader_spec.rb +1 -2
- metadata +68 -30
@@ -1,5 +1,5 @@
|
|
1
1
|
module EmailServerHelpers
|
2
|
-
REQUESTED_ATTRIBUTES =
|
2
|
+
REQUESTED_ATTRIBUTES = ["BODY[]"].freeze
|
3
3
|
DEFAULT_EMAIL = "address@example.org".freeze
|
4
4
|
|
5
5
|
def send_email(folder, options)
|
@@ -28,7 +28,7 @@ module EmailServerHelpers
|
|
28
28
|
end
|
29
29
|
|
30
30
|
def server_message_to_body(message)
|
31
|
-
message["
|
31
|
+
message["BODY[]"]
|
32
32
|
end
|
33
33
|
|
34
34
|
def server_fetch_email(folder, uid)
|
@@ -1,40 +1,27 @@
|
|
1
1
|
describe Email::Provider do
|
2
|
-
subject { described_class.new(:gmail) }
|
3
|
-
|
4
2
|
describe ".for_address" do
|
5
3
|
context "with known providers" do
|
6
4
|
[
|
7
|
-
["
|
8
|
-
["fastmail.fm",
|
9
|
-
|
10
|
-
|
5
|
+
["fastmail.com", "Fastmail .com", Email::Provider::Fastmail],
|
6
|
+
["fastmail.fm", "Fastmail .fm", Email::Provider::Fastmail],
|
7
|
+
["gmail.com", "GMail", Email::Provider::GMail],
|
8
|
+
["icloud.com", "Apple Mail icloud.com", Email::Provider::AppleMail],
|
9
|
+
["mac.com", "Apple Mail mac.com", Email::Provider::AppleMail],
|
10
|
+
["me.com", "Apple Mail me.com", Email::Provider::AppleMail]
|
11
|
+
].each do |domain, name, klass|
|
12
|
+
it "recognizes #{name} addresses" do
|
11
13
|
address = "foo@#{domain}"
|
12
|
-
expect(described_class.for_address(address)
|
14
|
+
expect(described_class.for_address(address)).to be_a(klass)
|
13
15
|
end
|
14
16
|
end
|
15
17
|
end
|
16
18
|
|
17
19
|
context "with unknown providers" do
|
18
20
|
it "returns a default provider" do
|
19
|
-
result = described_class.for_address("foo@unknown.com")
|
20
|
-
expect(result).to eq(:default)
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
describe "#options" do
|
26
|
-
it "returns options" do
|
27
|
-
expect(subject.options).to be_a(Hash)
|
28
|
-
end
|
21
|
+
result = described_class.for_address("foo@unknown.com")
|
29
22
|
|
30
|
-
|
31
|
-
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
describe "#host" do
|
36
|
-
it "returns host" do
|
37
|
-
expect(subject.host).to eq("imap.gmail.com")
|
23
|
+
expect(result).to be_a(Email::Provider::Default)
|
24
|
+
end
|
38
25
|
end
|
39
26
|
end
|
40
27
|
end
|
@@ -14,8 +14,10 @@ describe Imap::Backup::Account::Connection do
|
|
14
14
|
|
15
15
|
subject { described_class.new(options) }
|
16
16
|
|
17
|
-
let(:
|
18
|
-
instance_double(
|
17
|
+
let(:client) do
|
18
|
+
instance_double(
|
19
|
+
Imap::Backup::Client::Default, authenticate: nil, login: nil, disconnect: nil
|
20
|
+
)
|
19
21
|
end
|
20
22
|
let(:imap_folders) { [] }
|
21
23
|
let(:options) do
|
@@ -45,15 +47,14 @@ describe Imap::Backup::Account::Connection do
|
|
45
47
|
let(:new_uid_validity) { nil }
|
46
48
|
|
47
49
|
before do
|
48
|
-
allow(
|
49
|
-
allow(
|
50
|
-
allow(imap).to receive(:list).with(ROOT_NAME, "*") { imap_folders }
|
50
|
+
allow(Imap::Backup::Client::Default).to receive(:new) { client }
|
51
|
+
allow(client).to receive(:list) { imap_folders }
|
51
52
|
allow(Imap::Backup::Utils).to receive(:make_folder)
|
52
53
|
end
|
53
54
|
|
54
55
|
shared_examples "connects to IMAP" do
|
55
56
|
it "logs in to the imap server" do
|
56
|
-
expect(
|
57
|
+
expect(client).to have_received(:login)
|
57
58
|
end
|
58
59
|
end
|
59
60
|
|
@@ -76,48 +77,34 @@ describe Imap::Backup::Account::Connection do
|
|
76
77
|
end
|
77
78
|
end
|
78
79
|
|
79
|
-
describe "#
|
80
|
-
let(:result) { subject.
|
80
|
+
describe "#client" do
|
81
|
+
let(:result) { subject.client }
|
81
82
|
|
82
83
|
it "returns the IMAP connection" do
|
83
|
-
expect(result).to eq(
|
84
|
+
expect(result).to eq(client)
|
84
85
|
end
|
85
86
|
|
86
87
|
it "uses the password" do
|
87
88
|
result
|
88
89
|
|
89
|
-
expect(
|
90
|
-
end
|
91
|
-
|
92
|
-
context "with the GMail IMAP server" do
|
93
|
-
let(:server) { GMAIL_IMAP_SERVER }
|
94
|
-
let(:refresh_token) { true }
|
95
|
-
let(:result) { nil }
|
96
|
-
|
97
|
-
context "when the password is not our copy of a GMail refresh token" do
|
98
|
-
it "uses the password" do
|
99
|
-
subject.imap
|
100
|
-
|
101
|
-
expect(imap).to have_received(:login).with(USERNAME, PASSWORD)
|
102
|
-
end
|
103
|
-
end
|
90
|
+
expect(client).to have_received(:login).with(USERNAME, PASSWORD)
|
104
91
|
end
|
105
92
|
|
106
93
|
context "when the first login attempt fails" do
|
107
94
|
before do
|
108
95
|
outcomes = [-> { raise EOFError }, -> { true }]
|
109
|
-
allow(
|
96
|
+
allow(client).to receive(:login) { outcomes.shift.call }
|
110
97
|
end
|
111
98
|
|
112
99
|
it "retries" do
|
113
|
-
subject.
|
100
|
+
subject.client
|
114
101
|
|
115
|
-
expect(
|
102
|
+
expect(client).to have_received(:login).twice
|
116
103
|
end
|
117
104
|
end
|
118
105
|
|
119
106
|
context "when run" do
|
120
|
-
before { subject.
|
107
|
+
before { subject.client }
|
121
108
|
|
122
109
|
include_examples "connects to IMAP"
|
123
110
|
end
|
@@ -125,22 +112,12 @@ describe Imap::Backup::Account::Connection do
|
|
125
112
|
|
126
113
|
describe "#folders" do
|
127
114
|
let(:imap_folders) do
|
128
|
-
[
|
115
|
+
[BACKUP_FOLDER]
|
129
116
|
end
|
130
117
|
|
131
118
|
it "returns the list of folders" do
|
132
119
|
expect(subject.folders).to eq([BACKUP_FOLDER])
|
133
120
|
end
|
134
|
-
|
135
|
-
context "with non-ASCII folder names" do
|
136
|
-
let(:imap_folders) do
|
137
|
-
[instance_double(Net::IMAP::MailboxList, name: "Gel&APY-scht")]
|
138
|
-
end
|
139
|
-
|
140
|
-
it "converts them to UTF-8" do
|
141
|
-
expect(subject.folders).to eq(["Gelöscht"])
|
142
|
-
end
|
143
|
-
end
|
144
121
|
end
|
145
122
|
|
146
123
|
describe "#status" do
|
@@ -208,9 +185,7 @@ describe Imap::Backup::Account::Connection do
|
|
208
185
|
end
|
209
186
|
|
210
187
|
context "without supplied config_folders" do
|
211
|
-
let(:imap_folders)
|
212
|
-
[instance_double(Net::IMAP::MailboxList, name: ROOT_NAME)]
|
213
|
-
end
|
188
|
+
let(:imap_folders) { [ROOT_NAME] }
|
214
189
|
|
215
190
|
before do
|
216
191
|
allow(Imap::Backup::Account::Folder).to receive(:new).
|
@@ -241,7 +216,7 @@ describe Imap::Backup::Account::Connection do
|
|
241
216
|
|
242
217
|
context "when the imap server doesn't return folders" do
|
243
218
|
let(:config_folders) { nil }
|
244
|
-
let(:imap_folders) {
|
219
|
+
let(:imap_folders) { [] }
|
245
220
|
|
246
221
|
it "fails" do
|
247
222
|
expect do
|
@@ -389,10 +364,10 @@ describe Imap::Backup::Account::Connection do
|
|
389
364
|
|
390
365
|
describe "#reconnect" do
|
391
366
|
context "when the IMAP connection has been used" do
|
392
|
-
before { subject.
|
367
|
+
before { subject.client }
|
393
368
|
|
394
369
|
it "disconnects from the server" do
|
395
|
-
expect(
|
370
|
+
expect(client).to receive(:disconnect)
|
396
371
|
|
397
372
|
subject.reconnect
|
398
373
|
end
|
@@ -400,26 +375,26 @@ describe Imap::Backup::Account::Connection do
|
|
400
375
|
|
401
376
|
context "when the IMAP connection has not been used" do
|
402
377
|
it "does not disconnect from the server" do
|
403
|
-
expect(
|
378
|
+
expect(client).to_not receive(:disconnect)
|
404
379
|
|
405
380
|
subject.reconnect
|
406
381
|
end
|
407
382
|
end
|
408
383
|
|
409
384
|
it "causes reconnection on future access" do
|
410
|
-
expect(
|
385
|
+
expect(Imap::Backup::Client::Default).to receive(:new)
|
411
386
|
|
412
387
|
subject.reconnect
|
413
|
-
subject.
|
388
|
+
subject.client
|
414
389
|
end
|
415
390
|
end
|
416
391
|
|
417
392
|
describe "#disconnect" do
|
418
393
|
context "when the IMAP connection has been used" do
|
419
394
|
it "disconnects from the server" do
|
420
|
-
subject.
|
395
|
+
subject.client
|
421
396
|
|
422
|
-
expect(
|
397
|
+
expect(client).to receive(:disconnect)
|
423
398
|
|
424
399
|
subject.disconnect
|
425
400
|
end
|
@@ -427,7 +402,7 @@ describe Imap::Backup::Account::Connection do
|
|
427
402
|
|
428
403
|
context "when the IMAP connection has not been used" do
|
429
404
|
it "does not disconnect from the server" do
|
430
|
-
expect(
|
405
|
+
expect(client).to_not receive(:disconnect)
|
431
406
|
|
432
407
|
subject.disconnect
|
433
408
|
end
|
@@ -6,9 +6,9 @@ describe Imap::Backup::Account::Folder do
|
|
6
6
|
|
7
7
|
subject { described_class.new(connection, FOLDER_NAME) }
|
8
8
|
|
9
|
-
let(:
|
9
|
+
let(:client) do
|
10
10
|
instance_double(
|
11
|
-
|
11
|
+
Imap::Backup::Client::Default,
|
12
12
|
append: append_response,
|
13
13
|
create: nil,
|
14
14
|
examine: nil,
|
@@ -16,7 +16,7 @@ describe Imap::Backup::Account::Folder do
|
|
16
16
|
)
|
17
17
|
end
|
18
18
|
let(:connection) do
|
19
|
-
instance_double(Imap::Backup::Account::Connection,
|
19
|
+
instance_double(Imap::Backup::Account::Connection, client: client)
|
20
20
|
end
|
21
21
|
let(:missing_mailbox_data) do
|
22
22
|
OpenStruct.new(text: "Unknown Mailbox: #{FOLDER_NAME}")
|
@@ -31,7 +31,7 @@ describe Imap::Backup::Account::Folder do
|
|
31
31
|
describe "#uids" do
|
32
32
|
let(:uids) { [5678, 123] }
|
33
33
|
|
34
|
-
before { allow(
|
34
|
+
before { allow(client).to receive(:uid_search) { uids } }
|
35
35
|
|
36
36
|
it "lists available messages" do
|
37
37
|
expect(subject.uids).to eq(uids.reverse)
|
@@ -39,7 +39,7 @@ describe Imap::Backup::Account::Folder do
|
|
39
39
|
|
40
40
|
context "with missing mailboxes" do
|
41
41
|
before do
|
42
|
-
allow(
|
42
|
+
allow(client).to receive(:examine).
|
43
43
|
with(ENCODED_FOLDER_NAME).and_raise(missing_mailbox_error)
|
44
44
|
end
|
45
45
|
|
@@ -54,7 +54,7 @@ describe Imap::Backup::Account::Folder do
|
|
54
54
|
end
|
55
55
|
|
56
56
|
before do
|
57
|
-
allow(
|
57
|
+
allow(client).to receive(:examine).
|
58
58
|
with(ENCODED_FOLDER_NAME).and_raise(missing_mailbox_error)
|
59
59
|
end
|
60
60
|
|
@@ -66,19 +66,19 @@ describe Imap::Backup::Account::Folder do
|
|
66
66
|
|
67
67
|
describe "#fetch" do
|
68
68
|
let(:message_body) { instance_double(String, force_encoding: nil) }
|
69
|
-
let(:attributes) { {"
|
69
|
+
let(:attributes) { {"BODY[]" => message_body, "other" => "xxx"} }
|
70
70
|
let(:fetch_data_item) do
|
71
71
|
instance_double(Net::IMAP::FetchData, attr: attributes)
|
72
72
|
end
|
73
73
|
|
74
|
-
before { allow(
|
74
|
+
before { allow(client).to receive(:uid_fetch) { [fetch_data_item] } }
|
75
75
|
|
76
76
|
it "returns the message" do
|
77
|
-
expect(subject.fetch(123)).to eq(
|
77
|
+
expect(subject.fetch(123)).to eq(message_body)
|
78
78
|
end
|
79
79
|
|
80
80
|
context "when the server responds with nothing" do
|
81
|
-
before { allow(
|
81
|
+
before { allow(client).to receive(:uid_fetch) { nil } }
|
82
82
|
|
83
83
|
it "is nil" do
|
84
84
|
expect(subject.fetch(123)).to be_nil
|
@@ -87,7 +87,7 @@ describe Imap::Backup::Account::Folder do
|
|
87
87
|
|
88
88
|
context "when the mailbox doesn't exist" do
|
89
89
|
before do
|
90
|
-
allow(
|
90
|
+
allow(client).to receive(:examine).
|
91
91
|
with(ENCODED_FOLDER_NAME).and_raise(missing_mailbox_error)
|
92
92
|
end
|
93
93
|
|
@@ -96,7 +96,7 @@ describe Imap::Backup::Account::Folder do
|
|
96
96
|
end
|
97
97
|
end
|
98
98
|
|
99
|
-
context "when the response doesn't
|
99
|
+
context "when the response doesn't include 'BODY[]'" do
|
100
100
|
let(:attributes) { {} }
|
101
101
|
|
102
102
|
it "is nil" do
|
@@ -107,13 +107,13 @@ describe Imap::Backup::Account::Folder do
|
|
107
107
|
context "when the first fetch_uid attempts fail" do
|
108
108
|
before do
|
109
109
|
outcomes = [-> { raise EOFError }, -> { [fetch_data_item] }]
|
110
|
-
allow(
|
110
|
+
allow(client).to receive(:uid_fetch) { outcomes.shift.call }
|
111
111
|
end
|
112
112
|
|
113
113
|
it "retries" do
|
114
114
|
subject.fetch(123)
|
115
115
|
|
116
|
-
expect(
|
116
|
+
expect(client).to have_received(:uid_fetch).twice
|
117
117
|
end
|
118
118
|
|
119
119
|
it "succeeds" do
|
@@ -137,7 +137,7 @@ describe Imap::Backup::Account::Folder do
|
|
137
137
|
|
138
138
|
context "when the folder doesn't exist" do
|
139
139
|
before do
|
140
|
-
allow(
|
140
|
+
allow(client).to receive(:examine).
|
141
141
|
with(ENCODED_FOLDER_NAME).and_raise(missing_mailbox_error)
|
142
142
|
end
|
143
143
|
|
@@ -150,7 +150,7 @@ describe Imap::Backup::Account::Folder do
|
|
150
150
|
describe "#create" do
|
151
151
|
context "when the folder exists" do
|
152
152
|
it "is does not create the folder" do
|
153
|
-
expect(
|
153
|
+
expect(client).to_not receive(:create)
|
154
154
|
|
155
155
|
subject.create
|
156
156
|
end
|
@@ -158,18 +158,18 @@ describe Imap::Backup::Account::Folder do
|
|
158
158
|
|
159
159
|
context "when the folder doesn't exist" do
|
160
160
|
before do
|
161
|
-
allow(
|
161
|
+
allow(client).to receive(:examine).
|
162
162
|
with(ENCODED_FOLDER_NAME).and_raise(missing_mailbox_error)
|
163
163
|
end
|
164
164
|
|
165
165
|
it "creates the folder" do
|
166
|
-
expect(
|
166
|
+
expect(client).to receive(:create)
|
167
167
|
|
168
168
|
subject.create
|
169
169
|
end
|
170
170
|
|
171
171
|
it "encodes the folder name" do
|
172
|
-
expect(
|
172
|
+
expect(client).to receive(:create).with(ENCODED_FOLDER_NAME)
|
173
173
|
|
174
174
|
subject.create
|
175
175
|
end
|
@@ -185,7 +185,7 @@ describe Imap::Backup::Account::Folder do
|
|
185
185
|
|
186
186
|
context "when the folder doesn't exist" do
|
187
187
|
before do
|
188
|
-
allow(
|
188
|
+
allow(client).to receive(:examine).
|
189
189
|
with(ENCODED_FOLDER_NAME).and_raise(missing_mailbox_error)
|
190
190
|
end
|
191
191
|
|
@@ -211,13 +211,13 @@ describe Imap::Backup::Account::Folder do
|
|
211
211
|
end
|
212
212
|
|
213
213
|
it "appends the message" do
|
214
|
-
expect(
|
214
|
+
expect(client).to receive(:append)
|
215
215
|
|
216
216
|
subject.append(message)
|
217
217
|
end
|
218
218
|
|
219
219
|
it "sets the date and time" do
|
220
|
-
expect(
|
220
|
+
expect(client).to receive(:append).
|
221
221
|
with(anything, anything, anything, message_date)
|
222
222
|
|
223
223
|
subject.append(message)
|
@@ -0,0 +1,70 @@
|
|
1
|
+
describe Imap::Backup::CLI::Local do
|
2
|
+
let(:list) do
|
3
|
+
instance_double(Imap::Backup::Configuration::List, accounts: accounts)
|
4
|
+
end
|
5
|
+
let(:accounts) { [{username: email}] }
|
6
|
+
let(:connection) do
|
7
|
+
instance_double(
|
8
|
+
Imap::Backup::Account::Connection,
|
9
|
+
local_folders: local_folders
|
10
|
+
)
|
11
|
+
end
|
12
|
+
let(:local_folders) { [[serializer, folder]] }
|
13
|
+
let(:folder) { instance_double(Imap::Backup::Account::Folder, name: "bar") }
|
14
|
+
let(:serializer) do
|
15
|
+
instance_double(
|
16
|
+
Imap::Backup::Serializer::Mbox,
|
17
|
+
uids: uids,
|
18
|
+
each_message: [[123, message]]
|
19
|
+
)
|
20
|
+
end
|
21
|
+
let(:uids) { ["123"] }
|
22
|
+
let(:message) do
|
23
|
+
instance_double(
|
24
|
+
Email::Mboxrd::Message,
|
25
|
+
date: Date.today,
|
26
|
+
subject: "Ciao",
|
27
|
+
supplied_body: "Supplied"
|
28
|
+
)
|
29
|
+
end
|
30
|
+
let(:email) { "foo@example.com" }
|
31
|
+
|
32
|
+
before do
|
33
|
+
allow(Kernel).to receive(:puts)
|
34
|
+
allow(Imap::Backup::Configuration::List).to receive(:new) { list }
|
35
|
+
allow(Imap::Backup::Account::Connection).to receive(:new) { connection }
|
36
|
+
allow(Mail).to receive(:new) { mail }
|
37
|
+
end
|
38
|
+
|
39
|
+
describe "accounts" do
|
40
|
+
it "lists configured emails" do
|
41
|
+
subject.accounts
|
42
|
+
|
43
|
+
expect(Kernel).to have_received(:puts).with(email)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe "folders" do
|
48
|
+
it "lists downloaded folders in quotes" do
|
49
|
+
subject.folders(email)
|
50
|
+
|
51
|
+
expect(Kernel).to have_received(:puts).with(%("bar"))
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe "list" do
|
56
|
+
it "lists downloaded emails" do
|
57
|
+
subject.list(email, "bar")
|
58
|
+
|
59
|
+
expect(Kernel).to have_received(:puts).with(/Ciao/)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe "show" do
|
64
|
+
it "prints a downloaded email" do
|
65
|
+
subject.show(email, "bar", "123")
|
66
|
+
|
67
|
+
expect(Kernel).to have_received(:puts).with("Supplied")
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
describe Imap::Backup::CLI::Utils do
|
2
|
+
let(:list) do
|
3
|
+
instance_double(Imap::Backup::Configuration::List, accounts: accounts)
|
4
|
+
end
|
5
|
+
let(:accounts) { [{username: email}] }
|
6
|
+
let(:connection) do
|
7
|
+
instance_double(
|
8
|
+
Imap::Backup::Account::Connection,
|
9
|
+
local_folders: local_folders
|
10
|
+
)
|
11
|
+
end
|
12
|
+
let(:local_folders) { [[serializer, folder]] }
|
13
|
+
let(:folder) do
|
14
|
+
instance_double(
|
15
|
+
Imap::Backup::Account::Folder,
|
16
|
+
exist?: true,
|
17
|
+
name: "name",
|
18
|
+
uid_validity: "uid_validity",
|
19
|
+
uids: %w(123 456)
|
20
|
+
)
|
21
|
+
end
|
22
|
+
let(:serializer) do
|
23
|
+
instance_double(
|
24
|
+
Imap::Backup::Serializer::Mbox,
|
25
|
+
uids: %w(123 789),
|
26
|
+
apply_uid_validity: nil,
|
27
|
+
save: nil
|
28
|
+
)
|
29
|
+
end
|
30
|
+
let(:email) { "foo@example.com" }
|
31
|
+
|
32
|
+
before do
|
33
|
+
allow(Imap::Backup::Configuration::List).to receive(:new) { list }
|
34
|
+
allow(Imap::Backup::Account::Connection).to receive(:new) { connection }
|
35
|
+
end
|
36
|
+
|
37
|
+
describe "ignore_history" do
|
38
|
+
it "ensures the local UID validity matches the server" do
|
39
|
+
subject.ignore_history(email)
|
40
|
+
|
41
|
+
expect(serializer).to have_received(:apply_uid_validity).with("uid_validity")
|
42
|
+
end
|
43
|
+
|
44
|
+
it "fills the local folder with fake emails" do
|
45
|
+
subject.ignore_history(email)
|
46
|
+
|
47
|
+
expect(serializer).to have_received(:save).with("456", /From: fake@email.com/)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
describe Imap::Backup::Client::Default do
|
2
|
+
subject { described_class.new("server", {}) }
|
3
|
+
|
4
|
+
let(:imap) { instance_double(Net::IMAP, list: imap_folders) }
|
5
|
+
let(:imap_folders) { [] }
|
6
|
+
|
7
|
+
before do
|
8
|
+
allow(Net::IMAP).to receive(:new) { imap }
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "#list" do
|
12
|
+
context "with non-ASCII folder names" do
|
13
|
+
let(:imap_folders) do
|
14
|
+
[instance_double(Net::IMAP::MailboxList, name: "Gel&APY-scht")]
|
15
|
+
end
|
16
|
+
|
17
|
+
it "converts them to UTF-8" do
|
18
|
+
expect(subject.list).to eq(["Gelöscht"])
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
describe Imap::Backup::Configuration::ConnectionTester do
|
2
2
|
describe ".test" do
|
3
3
|
let(:connection) do
|
4
|
-
instance_double(Imap::Backup::Account::Connection,
|
4
|
+
instance_double(Imap::Backup::Account::Connection, client: nil)
|
5
5
|
end
|
6
6
|
|
7
7
|
before do
|
@@ -10,7 +10,7 @@ describe Imap::Backup::Configuration::ConnectionTester do
|
|
10
10
|
|
11
11
|
describe "call" do
|
12
12
|
it "tries to connect" do
|
13
|
-
expect(connection).to receive(:
|
13
|
+
expect(connection).to receive(:client)
|
14
14
|
|
15
15
|
subject.test("foo")
|
16
16
|
end
|
@@ -24,7 +24,7 @@ describe Imap::Backup::Configuration::ConnectionTester do
|
|
24
24
|
|
25
25
|
describe "failure" do
|
26
26
|
before do
|
27
|
-
allow(connection).to receive(:
|
27
|
+
allow(connection).to receive(:client).and_raise(error)
|
28
28
|
end
|
29
29
|
|
30
30
|
context "with no connection" do
|