imap-backup 6.0.0.rc2 → 6.0.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/imap-backup.gemspec +5 -1
- data/lib/cli_coverage.rb +11 -11
- data/lib/email/provider/base.rb +2 -0
- data/lib/email/provider/unknown.rb +2 -0
- data/lib/email/provider.rb +2 -0
- data/lib/imap/backup/account/connection/backup_folders.rb +27 -0
- data/lib/imap/backup/account/connection/client_factory.rb +54 -0
- data/lib/imap/backup/account/connection/folder_names.rb +26 -0
- data/lib/imap/backup/account/connection.rb +11 -95
- data/lib/imap/backup/account/folder.rb +9 -6
- data/lib/imap/backup/account.rb +3 -5
- data/lib/imap/backup/cli/backup.rb +1 -3
- data/lib/imap/backup/cli/helpers.rb +24 -22
- data/lib/imap/backup/cli/local.rb +20 -13
- data/lib/imap/backup/cli/migrate.rb +4 -10
- data/lib/imap/backup/cli/restore.rb +8 -7
- data/lib/imap/backup/cli/setup.rb +10 -8
- data/lib/imap/backup/cli/stats.rb +78 -0
- data/lib/imap/backup/cli/status.rb +2 -2
- data/lib/imap/backup/cli/utils.rb +4 -6
- data/lib/imap/backup/cli.rb +24 -3
- data/lib/imap/backup/configuration.rb +9 -11
- data/lib/imap/backup/downloader.rb +48 -30
- data/lib/imap/backup/migrator.rb +5 -5
- data/lib/imap/backup/sanitizer.rb +3 -2
- data/lib/imap/backup/serializer/appender.rb +49 -0
- data/lib/imap/backup/serializer/message_enumerator.rb +29 -0
- data/lib/imap/backup/serializer/unused_name_finder.rb +27 -0
- data/lib/imap/backup/serializer.rb +24 -78
- data/lib/imap/backup/setup/account/header.rb +75 -0
- data/lib/imap/backup/setup/account.rb +14 -91
- data/lib/imap/backup/setup/asker.rb +4 -15
- data/lib/imap/backup/setup/backup_path.rb +41 -0
- data/lib/imap/backup/setup/email.rb +45 -0
- data/lib/imap/backup/setup/folder_chooser.rb +3 -3
- data/lib/imap/backup/setup/helpers.rb +1 -1
- data/lib/imap/backup/setup.rb +5 -4
- data/lib/imap/backup/thunderbird/mailbox_exporter.rb +39 -20
- data/lib/imap/backup/uploader.rb +46 -8
- data/lib/imap/backup/utils.rb +1 -1
- data/lib/imap/backup/version.rb +1 -1
- data/lib/imap/backup.rb +0 -1
- metadata +31 -134
- data/spec/features/backup_spec.rb +0 -100
- data/spec/features/configuration/minimal_configuration.rb +0 -15
- data/spec/features/configuration/missing_configuration.rb +0 -14
- data/spec/features/folders_spec.rb +0 -36
- data/spec/features/helper.rb +0 -2
- data/spec/features/local/list_accounts_spec.rb +0 -12
- data/spec/features/local/list_emails_spec.rb +0 -21
- data/spec/features/local/list_folders_spec.rb +0 -21
- data/spec/features/local/show_an_email_spec.rb +0 -34
- data/spec/features/migrate_spec.rb +0 -35
- data/spec/features/remote/list_account_folders_spec.rb +0 -16
- data/spec/features/restore_spec.rb +0 -162
- data/spec/features/status_spec.rb +0 -43
- data/spec/features/support/aruba.rb +0 -78
- data/spec/features/support/backup_directory.rb +0 -43
- data/spec/features/support/email_server.rb +0 -110
- data/spec/features/support/shared/connection_context.rb +0 -14
- data/spec/features/support/shared/message_fixtures.rb +0 -16
- data/spec/fixtures/connection.yml +0 -7
- data/spec/spec_helper.rb +0 -15
- data/spec/support/fixtures.rb +0 -11
- data/spec/support/higline_test_helpers.rb +0 -8
- data/spec/support/silence_logging.rb +0 -7
- data/spec/unit/email/mboxrd/message_spec.rb +0 -177
- data/spec/unit/email/provider/apple_mail_spec.rb +0 -7
- data/spec/unit/email/provider/base_spec.rb +0 -11
- data/spec/unit/email/provider/fastmail_spec.rb +0 -7
- data/spec/unit/email/provider/gmail_spec.rb +0 -7
- data/spec/unit/email/provider_spec.rb +0 -27
- data/spec/unit/imap/backup/account/connection_spec.rb +0 -433
- data/spec/unit/imap/backup/account/folder_spec.rb +0 -261
- data/spec/unit/imap/backup/account_spec.rb +0 -246
- data/spec/unit/imap/backup/cli/accounts_spec.rb +0 -58
- data/spec/unit/imap/backup/cli/backup_spec.rb +0 -19
- data/spec/unit/imap/backup/cli/folders_spec.rb +0 -39
- data/spec/unit/imap/backup/cli/helpers_spec.rb +0 -87
- data/spec/unit/imap/backup/cli/local_spec.rb +0 -100
- data/spec/unit/imap/backup/cli/migrate_spec.rb +0 -80
- data/spec/unit/imap/backup/cli/restore_spec.rb +0 -67
- data/spec/unit/imap/backup/cli/setup_spec.rb +0 -17
- data/spec/unit/imap/backup/cli/utils_spec.rb +0 -125
- data/spec/unit/imap/backup/cli_spec.rb +0 -93
- data/spec/unit/imap/backup/client/apple_mail_spec.rb +0 -9
- data/spec/unit/imap/backup/client/default_spec.rb +0 -22
- data/spec/unit/imap/backup/configuration_spec.rb +0 -238
- data/spec/unit/imap/backup/downloader_spec.rb +0 -96
- data/spec/unit/imap/backup/logger_spec.rb +0 -48
- data/spec/unit/imap/backup/migrator_spec.rb +0 -58
- data/spec/unit/imap/backup/sanitizer_spec.rb +0 -42
- data/spec/unit/imap/backup/serializer/directory_spec.rb +0 -37
- data/spec/unit/imap/backup/serializer/imap_spec.rb +0 -218
- data/spec/unit/imap/backup/serializer/mbox_enumerator_spec.rb +0 -45
- data/spec/unit/imap/backup/serializer/mbox_spec.rb +0 -101
- data/spec/unit/imap/backup/serializer_spec.rb +0 -296
- data/spec/unit/imap/backup/setup/account_spec.rb +0 -461
- data/spec/unit/imap/backup/setup/asker_spec.rb +0 -137
- data/spec/unit/imap/backup/setup/connection_tester_spec.rb +0 -51
- data/spec/unit/imap/backup/setup/folder_chooser_spec.rb +0 -146
- data/spec/unit/imap/backup/setup/helpers_spec.rb +0 -15
- data/spec/unit/imap/backup/setup_spec.rb +0 -301
- data/spec/unit/imap/backup/thunderbird/mailbox_exporter_spec.rb +0 -116
- data/spec/unit/imap/backup/uploader_spec.rb +0 -54
- data/spec/unit/imap/backup/utils_spec.rb +0 -92
- data/spec/unit/retry_on_error_spec.rb +0 -34
|
@@ -1,238 +0,0 @@
|
|
|
1
|
-
require "json"
|
|
2
|
-
require "os"
|
|
3
|
-
|
|
4
|
-
# rubocop:disable RSpec/PredicateMatcher
|
|
5
|
-
|
|
6
|
-
describe Imap::Backup::Configuration do
|
|
7
|
-
let(:directory) { "/base/path" }
|
|
8
|
-
let(:file_path) { File.join(directory, "/config.json") }
|
|
9
|
-
let(:file_exists) { true }
|
|
10
|
-
let(:directory_exists) { true }
|
|
11
|
-
let(:debug) { true }
|
|
12
|
-
let(:configuration) { data.to_json }
|
|
13
|
-
let(:data) { {debug: debug, accounts: accounts.map(&:to_h)} }
|
|
14
|
-
let(:accounts) { [account1, account2] }
|
|
15
|
-
let(:account1) { Imap::Backup::Account.new({username: "username1"}) }
|
|
16
|
-
let(:account2) { Imap::Backup::Account.new({username: "username2"}) }
|
|
17
|
-
|
|
18
|
-
before do
|
|
19
|
-
stub_const(
|
|
20
|
-
"Imap::Backup::Configuration::CONFIGURATION_DIRECTORY", directory
|
|
21
|
-
)
|
|
22
|
-
allow(File).to receive(:directory?).with(directory) { directory_exists }
|
|
23
|
-
allow(File).to receive(:exist?).and_call_original
|
|
24
|
-
allow(File).to receive(:exist?).with(file_path) { file_exists }
|
|
25
|
-
allow(Imap::Backup::Utils).
|
|
26
|
-
to receive(:stat).with(directory) { 0o700 }
|
|
27
|
-
allow(Imap::Backup::Utils).
|
|
28
|
-
to receive(:stat).with(file_path) { 0o600 }
|
|
29
|
-
allow(Imap::Backup::Utils).to receive(:check_permissions) { nil }
|
|
30
|
-
allow(File).to receive(:read).with(file_path) { configuration }
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
describe ".exist?" do
|
|
34
|
-
[true, false].each do |exists|
|
|
35
|
-
state = exists ? "exists" : "doesn't exist"
|
|
36
|
-
context "when the file #{state}" do
|
|
37
|
-
let(:file_exists) { exists }
|
|
38
|
-
|
|
39
|
-
it "returns #{exists}" do
|
|
40
|
-
expect(described_class.exist?).to eq(file_exists)
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
describe "#path" do
|
|
47
|
-
it "is the directory containing the configuration file" do
|
|
48
|
-
expect(subject.path).to eq(directory)
|
|
49
|
-
end
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
describe "#modified?" do
|
|
53
|
-
context "with modified accounts" do
|
|
54
|
-
before { subject.accounts[0].username = "changed" }
|
|
55
|
-
|
|
56
|
-
it "is true" do
|
|
57
|
-
expect(subject.modified?).to be_truthy
|
|
58
|
-
end
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
context "with accounts flagged 'delete'" do
|
|
62
|
-
before { subject.accounts[0].mark_for_deletion }
|
|
63
|
-
|
|
64
|
-
it "is true" do
|
|
65
|
-
expect(subject.modified?).to be_truthy
|
|
66
|
-
end
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
context "without accounts flagged 'modified'" do
|
|
70
|
-
it "is false" do
|
|
71
|
-
expect(subject.modified?).to be_falsey
|
|
72
|
-
end
|
|
73
|
-
end
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
describe "#debug?" do
|
|
77
|
-
context "when the debug flag is true" do
|
|
78
|
-
it "is true" do
|
|
79
|
-
expect(subject.debug?).to be_truthy
|
|
80
|
-
end
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
context "when the debug flag is false" do
|
|
84
|
-
let(:debug) { false }
|
|
85
|
-
|
|
86
|
-
it "is false" do
|
|
87
|
-
expect(subject.debug?).to be_falsey
|
|
88
|
-
end
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
context "when the debug flag is missing" do
|
|
92
|
-
let(:data) { {accounts: accounts} }
|
|
93
|
-
|
|
94
|
-
it "is false" do
|
|
95
|
-
expect(subject.debug?).to be_falsey
|
|
96
|
-
end
|
|
97
|
-
end
|
|
98
|
-
|
|
99
|
-
context "when the debug flag is neither true nor false" do
|
|
100
|
-
let(:debug) { "hi" }
|
|
101
|
-
|
|
102
|
-
it "is false" do
|
|
103
|
-
expect(subject.debug?).to be_falsey
|
|
104
|
-
end
|
|
105
|
-
end
|
|
106
|
-
end
|
|
107
|
-
|
|
108
|
-
describe "#debug=" do
|
|
109
|
-
before { subject.debug = debug }
|
|
110
|
-
|
|
111
|
-
context "when the supplied value is true" do
|
|
112
|
-
it "sets the flag to true" do
|
|
113
|
-
expect(subject.debug?).to be_truthy
|
|
114
|
-
end
|
|
115
|
-
end
|
|
116
|
-
|
|
117
|
-
context "when the supplied value is false" do
|
|
118
|
-
let(:debug) { false }
|
|
119
|
-
|
|
120
|
-
it "sets the flag to false" do
|
|
121
|
-
expect(subject.debug?).to be_falsey
|
|
122
|
-
end
|
|
123
|
-
end
|
|
124
|
-
|
|
125
|
-
context "when the supplied value is neither true nor false" do
|
|
126
|
-
let(:debug) { "ciao" }
|
|
127
|
-
|
|
128
|
-
it "sets the flag to false" do
|
|
129
|
-
expect(subject.debug?).to be_falsey
|
|
130
|
-
end
|
|
131
|
-
end
|
|
132
|
-
end
|
|
133
|
-
|
|
134
|
-
describe "#save" do
|
|
135
|
-
subject { described_class.new }
|
|
136
|
-
|
|
137
|
-
let(:directory_exists) { false }
|
|
138
|
-
let(:file) { instance_double(File, write: nil) }
|
|
139
|
-
|
|
140
|
-
before do
|
|
141
|
-
allow(FileUtils).to receive(:mkdir)
|
|
142
|
-
allow(FileUtils).to receive(:chmod)
|
|
143
|
-
allow(File).to receive(:open).with(file_path, "w").and_yield(file)
|
|
144
|
-
allow(JSON).to receive(:pretty_generate) { "JSON output" }
|
|
145
|
-
end
|
|
146
|
-
|
|
147
|
-
it "creates the config directory" do
|
|
148
|
-
expect(FileUtils).to receive(:mkdir).with(directory)
|
|
149
|
-
|
|
150
|
-
subject.save
|
|
151
|
-
end
|
|
152
|
-
|
|
153
|
-
it "saves the configuration" do
|
|
154
|
-
expect(file).to receive(:write).with("JSON output")
|
|
155
|
-
|
|
156
|
-
subject.save
|
|
157
|
-
end
|
|
158
|
-
|
|
159
|
-
it "uses the Account#to_h method" do
|
|
160
|
-
allow(subject.accounts[0]).to receive(:to_h) { "Account1" }
|
|
161
|
-
allow(subject.accounts[1]).to receive(:to_h) { "Account2" }
|
|
162
|
-
|
|
163
|
-
expect(JSON).to receive(:pretty_generate).
|
|
164
|
-
with(hash_including({accounts: ["Account1", "Account2"]}))
|
|
165
|
-
|
|
166
|
-
subject.save
|
|
167
|
-
end
|
|
168
|
-
|
|
169
|
-
context "when accounts are to be deleted" do
|
|
170
|
-
let(:accounts) do
|
|
171
|
-
[
|
|
172
|
-
{name: "keep_me"},
|
|
173
|
-
{name: "delete_me", delete: true}
|
|
174
|
-
]
|
|
175
|
-
end
|
|
176
|
-
|
|
177
|
-
before do
|
|
178
|
-
allow(subject.accounts[0]).to receive(:to_h) { "Account1" }
|
|
179
|
-
allow(subject.accounts[1]).to receive(:to_h) { "Account2" }
|
|
180
|
-
subject.accounts[0].mark_for_deletion
|
|
181
|
-
end
|
|
182
|
-
|
|
183
|
-
it "does not save them" do
|
|
184
|
-
expect(JSON).to receive(:pretty_generate).
|
|
185
|
-
with(hash_including({accounts: ["Account2"]}))
|
|
186
|
-
|
|
187
|
-
subject.save
|
|
188
|
-
end
|
|
189
|
-
end
|
|
190
|
-
|
|
191
|
-
context "when file permissions are too open" do
|
|
192
|
-
context "when on UNIX" do
|
|
193
|
-
before do
|
|
194
|
-
allow(OS).to receive(:windows?) { false }
|
|
195
|
-
end
|
|
196
|
-
|
|
197
|
-
it "sets them to 0600" do
|
|
198
|
-
expect(FileUtils).to receive(:chmod).with(0o600, file_path)
|
|
199
|
-
|
|
200
|
-
subject.save
|
|
201
|
-
end
|
|
202
|
-
end
|
|
203
|
-
end
|
|
204
|
-
|
|
205
|
-
context "when the configuration file is missing" do
|
|
206
|
-
let(:file_exists) { false }
|
|
207
|
-
|
|
208
|
-
it "doesn't fail" do
|
|
209
|
-
expect do
|
|
210
|
-
subject.save
|
|
211
|
-
end.to_not raise_error
|
|
212
|
-
end
|
|
213
|
-
end
|
|
214
|
-
|
|
215
|
-
context "when on UNIX" do
|
|
216
|
-
before do
|
|
217
|
-
allow(OS).to receive(:windows?) { false }
|
|
218
|
-
end
|
|
219
|
-
|
|
220
|
-
context "when the config file permissions are too lax" do
|
|
221
|
-
let(:file_exists) { true }
|
|
222
|
-
|
|
223
|
-
before do
|
|
224
|
-
allow(Imap::Backup::Utils).to receive(:check_permissions).
|
|
225
|
-
with(file_path, 0o600).and_raise("Error")
|
|
226
|
-
end
|
|
227
|
-
|
|
228
|
-
it "fails" do
|
|
229
|
-
expect do
|
|
230
|
-
subject.save
|
|
231
|
-
end.to raise_error(RuntimeError, "Error")
|
|
232
|
-
end
|
|
233
|
-
end
|
|
234
|
-
end
|
|
235
|
-
end
|
|
236
|
-
end
|
|
237
|
-
|
|
238
|
-
# rubocop:enable RSpec/PredicateMatcher
|
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
describe Imap::Backup::Downloader do
|
|
2
|
-
describe "#run" do
|
|
3
|
-
subject { described_class.new(folder, serializer, **options) }
|
|
4
|
-
|
|
5
|
-
let(:body) { "blah" }
|
|
6
|
-
let(:folder) do
|
|
7
|
-
instance_double(
|
|
8
|
-
Imap::Backup::Account::Folder,
|
|
9
|
-
fetch_multi: [{uid: "111", body: body}],
|
|
10
|
-
name: "folder",
|
|
11
|
-
uids: remote_uids
|
|
12
|
-
)
|
|
13
|
-
end
|
|
14
|
-
let(:remote_uids) { %w(111 222 333) }
|
|
15
|
-
let(:serializer) do
|
|
16
|
-
instance_double(Imap::Backup::Serializer, append: nil, uids: local_uids)
|
|
17
|
-
end
|
|
18
|
-
let(:local_uids) { ["222"] }
|
|
19
|
-
let(:options) { {} }
|
|
20
|
-
|
|
21
|
-
context "with fetched messages" do
|
|
22
|
-
specify "are saved" do
|
|
23
|
-
expect(serializer).to receive(:append).with("111", body)
|
|
24
|
-
|
|
25
|
-
subject.run
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
context "with messages which are already present" do
|
|
30
|
-
specify "are skipped" do
|
|
31
|
-
expect(serializer).to_not receive(:append).with("222", anything)
|
|
32
|
-
|
|
33
|
-
subject.run
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
context "with failed fetches" do
|
|
38
|
-
specify "are skipped" do
|
|
39
|
-
allow(folder).to receive(:fetch_multi) { nil }
|
|
40
|
-
expect(serializer).to_not receive(:append)
|
|
41
|
-
|
|
42
|
-
subject.run
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
context "when the block size is greater than one" do
|
|
47
|
-
let(:remote_uids) { %w(111 999) }
|
|
48
|
-
let(:local_uids) { [] }
|
|
49
|
-
let(:options) { {multi_fetch_size: 2} }
|
|
50
|
-
|
|
51
|
-
context "when the first fetch fails" do
|
|
52
|
-
before do
|
|
53
|
-
allow(folder).to receive(:fetch_multi).with(["111", "999"]) { nil }
|
|
54
|
-
allow(folder).to receive(:fetch_multi).with(["111"]).
|
|
55
|
-
and_return([{uid: "111", body: body}]).
|
|
56
|
-
and_return([{uid: "999", body: body}])
|
|
57
|
-
|
|
58
|
-
subject.run
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
it "retries fetching messages singly" do
|
|
62
|
-
expect(serializer).to have_received(:append).with("111", body)
|
|
63
|
-
expect(serializer).to have_received(:append).with("999", body)
|
|
64
|
-
end
|
|
65
|
-
end
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
context "when no body is returned by the fetch" do
|
|
69
|
-
let(:remote_uids) { %w(111) }
|
|
70
|
-
|
|
71
|
-
before do
|
|
72
|
-
allow(folder).to receive(:fetch_multi).with(["111"]) { [{uid: "111", body: nil}] }
|
|
73
|
-
|
|
74
|
-
subject.run
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
it "skips the append" do
|
|
78
|
-
expect(serializer).to_not have_received(:append)
|
|
79
|
-
end
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
context "when the UID is not returned by the fetch" do
|
|
83
|
-
let(:remote_uids) { %w(111) }
|
|
84
|
-
|
|
85
|
-
before do
|
|
86
|
-
allow(folder).to receive(:fetch_multi).with(["111"]) { [{uid: nil, body: body}] }
|
|
87
|
-
|
|
88
|
-
subject.run
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
it "skips the append" do
|
|
92
|
-
expect(serializer).to_not have_received(:append)
|
|
93
|
-
end
|
|
94
|
-
end
|
|
95
|
-
end
|
|
96
|
-
end
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
require "net/imap"
|
|
2
|
-
|
|
3
|
-
module Imap::Backup
|
|
4
|
-
describe Logger do
|
|
5
|
-
describe ".setup_logging" do
|
|
6
|
-
let(:config) { instance_double(Configuration, debug?: debug) }
|
|
7
|
-
|
|
8
|
-
around do |example|
|
|
9
|
-
logger_previous = described_class.logger.level
|
|
10
|
-
net_imap_previous = Net::IMAP.debug
|
|
11
|
-
described_class.logger.level = 42
|
|
12
|
-
Net::IMAP.debug = 42
|
|
13
|
-
example.run
|
|
14
|
-
Net::IMAP.debug = net_imap_previous
|
|
15
|
-
described_class.logger.level = logger_previous
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
before do
|
|
19
|
-
allow(Configuration).to receive(:new) { config }
|
|
20
|
-
described_class.setup_logging
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
context "when config.debug?" do
|
|
24
|
-
let(:debug) { true }
|
|
25
|
-
|
|
26
|
-
it "sets logger level to debug" do
|
|
27
|
-
expect(described_class.logger.level).to eq(::Logger::Severity::DEBUG)
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
it "sets the Net::IMAP debug flag" do
|
|
31
|
-
expect(Net::IMAP.debug).to be_a(TrueClass)
|
|
32
|
-
end
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
context "when not config.debug?" do
|
|
36
|
-
let(:debug) { false }
|
|
37
|
-
|
|
38
|
-
it "sets logger level to error" do
|
|
39
|
-
expect(described_class.logger.level).to eq(::Logger::Severity::ERROR)
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
it "doesn't set the Net::IMAP debug flag" do
|
|
43
|
-
expect(Net::IMAP.debug).to be_a(FalseClass)
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
end
|
|
47
|
-
end
|
|
48
|
-
end
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
require "imap/backup/migrator"
|
|
2
|
-
|
|
3
|
-
module Imap::Backup
|
|
4
|
-
RSpec.describe Migrator do
|
|
5
|
-
subject { described_class.new(serializer, folder, reset: reset) }
|
|
6
|
-
|
|
7
|
-
let(:serializer) { instance_double(Serializer, uids: [1]) }
|
|
8
|
-
let(:folder) do
|
|
9
|
-
instance_double(
|
|
10
|
-
Account::Folder,
|
|
11
|
-
append: nil, clear: nil, create: nil, name: "name", uids: folder_uids
|
|
12
|
-
)
|
|
13
|
-
end
|
|
14
|
-
let(:folder_uids) { [] }
|
|
15
|
-
let(:reset) { false }
|
|
16
|
-
let(:messages) { [[1, message]] }
|
|
17
|
-
let(:message) { instance_double(Email::Mboxrd::Message, supplied_body: body) }
|
|
18
|
-
let(:body) { "body" }
|
|
19
|
-
|
|
20
|
-
before do
|
|
21
|
-
allow(serializer).to receive(:each_message) do
|
|
22
|
-
messages.enum_for(:each)
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
it "creates the folder" do
|
|
27
|
-
subject.run
|
|
28
|
-
|
|
29
|
-
expect(folder).to have_received(:create)
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
it "uploads messages" do
|
|
33
|
-
subject.run
|
|
34
|
-
|
|
35
|
-
expect(folder).to have_received(:append).with(message)
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
context "when the folder is not empty" do
|
|
39
|
-
let(:folder_uids) { [99] }
|
|
40
|
-
|
|
41
|
-
it "fails" do
|
|
42
|
-
expect do
|
|
43
|
-
subject.run
|
|
44
|
-
end.to raise_error(RuntimeError, /The destination folder 'name' is not empty/)
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
context "when `reset` is true" do
|
|
48
|
-
let(:reset) { true }
|
|
49
|
-
|
|
50
|
-
it "clears the folder" do
|
|
51
|
-
subject.run
|
|
52
|
-
|
|
53
|
-
expect(folder).to have_received(:clear)
|
|
54
|
-
end
|
|
55
|
-
end
|
|
56
|
-
end
|
|
57
|
-
end
|
|
58
|
-
end
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
module Imap::Backup
|
|
2
|
-
describe Sanitizer do
|
|
3
|
-
require "stringio"
|
|
4
|
-
|
|
5
|
-
subject { described_class.new(output) }
|
|
6
|
-
|
|
7
|
-
let(:output) { StringIO.new }
|
|
8
|
-
|
|
9
|
-
describe "#puts" do
|
|
10
|
-
it "delegates to output" do
|
|
11
|
-
subject.puts("x")
|
|
12
|
-
|
|
13
|
-
expect(output.string).to eq("x\n")
|
|
14
|
-
end
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
describe "#write" do
|
|
18
|
-
it "delegates to output" do
|
|
19
|
-
subject.write("x")
|
|
20
|
-
|
|
21
|
-
expect(output.string).to eq("x")
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
describe "#print" do
|
|
26
|
-
it "removes passwords from complete lines of text" do
|
|
27
|
-
subject.print("C: RUBY99 LOGIN xx) secret!!!!\netc")
|
|
28
|
-
|
|
29
|
-
expect(output.string).to eq("C: RUBY99 LOGIN xx) [PASSWORD REDACTED]\n")
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
describe "#flush" do
|
|
34
|
-
it "sanitizes remaining text" do
|
|
35
|
-
subject.print("before\nC: RUBY99 LOGIN xx) secret!!!!")
|
|
36
|
-
subject.flush
|
|
37
|
-
|
|
38
|
-
expect(output.string).to eq("before\nC: RUBY99 LOGIN xx) [PASSWORD REDACTED]\n")
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
end
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
module Imap::Backup
|
|
2
|
-
describe Serializer::Directory do
|
|
3
|
-
subject { described_class.new("path", "relative") }
|
|
4
|
-
|
|
5
|
-
let(:windows) { false }
|
|
6
|
-
|
|
7
|
-
before do
|
|
8
|
-
allow(File).to receive(:directory?) { false }
|
|
9
|
-
allow(Utils).to receive(:make_folder)
|
|
10
|
-
allow(OS).to receive(:windows?) { windows }
|
|
11
|
-
allow(Utils).to receive(:mode) { 0o600 }
|
|
12
|
-
allow(FileUtils).to receive(:chmod)
|
|
13
|
-
|
|
14
|
-
subject.ensure_exists
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
describe "#ensure_exists" do
|
|
18
|
-
context "when the directory doesn't exist" do
|
|
19
|
-
it "makes the directory" do
|
|
20
|
-
expect(Utils).to have_received(:make_folder)
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
it "sets permissions" do
|
|
25
|
-
expect(FileUtils).to have_received(:chmod)
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
context "when on Windows" do
|
|
29
|
-
let(:windows) { true }
|
|
30
|
-
|
|
31
|
-
it "doesn't set permissions" do
|
|
32
|
-
expect(FileUtils).to_not have_received(:chmod)
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
end
|