imap-backup 6.0.0.rc2 → 6.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (108) hide show
  1. checksums.yaml +4 -4
  2. data/imap-backup.gemspec +5 -1
  3. data/lib/cli_coverage.rb +11 -11
  4. data/lib/email/provider/base.rb +2 -0
  5. data/lib/email/provider/unknown.rb +2 -0
  6. data/lib/email/provider.rb +2 -0
  7. data/lib/imap/backup/account/connection/backup_folders.rb +27 -0
  8. data/lib/imap/backup/account/connection/client_factory.rb +54 -0
  9. data/lib/imap/backup/account/connection/folder_names.rb +26 -0
  10. data/lib/imap/backup/account/connection.rb +11 -95
  11. data/lib/imap/backup/account/folder.rb +9 -6
  12. data/lib/imap/backup/account.rb +3 -5
  13. data/lib/imap/backup/cli/backup.rb +1 -3
  14. data/lib/imap/backup/cli/helpers.rb +24 -22
  15. data/lib/imap/backup/cli/local.rb +20 -13
  16. data/lib/imap/backup/cli/migrate.rb +4 -10
  17. data/lib/imap/backup/cli/restore.rb +8 -7
  18. data/lib/imap/backup/cli/setup.rb +10 -8
  19. data/lib/imap/backup/cli/stats.rb +78 -0
  20. data/lib/imap/backup/cli/status.rb +2 -2
  21. data/lib/imap/backup/cli/utils.rb +4 -6
  22. data/lib/imap/backup/cli.rb +24 -3
  23. data/lib/imap/backup/configuration.rb +9 -11
  24. data/lib/imap/backup/downloader.rb +48 -30
  25. data/lib/imap/backup/migrator.rb +5 -5
  26. data/lib/imap/backup/sanitizer.rb +3 -2
  27. data/lib/imap/backup/serializer/appender.rb +49 -0
  28. data/lib/imap/backup/serializer/message_enumerator.rb +29 -0
  29. data/lib/imap/backup/serializer/unused_name_finder.rb +27 -0
  30. data/lib/imap/backup/serializer.rb +24 -78
  31. data/lib/imap/backup/setup/account/header.rb +75 -0
  32. data/lib/imap/backup/setup/account.rb +14 -91
  33. data/lib/imap/backup/setup/asker.rb +4 -15
  34. data/lib/imap/backup/setup/backup_path.rb +41 -0
  35. data/lib/imap/backup/setup/email.rb +45 -0
  36. data/lib/imap/backup/setup/folder_chooser.rb +3 -3
  37. data/lib/imap/backup/setup/helpers.rb +1 -1
  38. data/lib/imap/backup/setup.rb +5 -4
  39. data/lib/imap/backup/thunderbird/mailbox_exporter.rb +39 -20
  40. data/lib/imap/backup/uploader.rb +46 -8
  41. data/lib/imap/backup/utils.rb +1 -1
  42. data/lib/imap/backup/version.rb +1 -1
  43. data/lib/imap/backup.rb +0 -1
  44. metadata +31 -134
  45. data/spec/features/backup_spec.rb +0 -100
  46. data/spec/features/configuration/minimal_configuration.rb +0 -15
  47. data/spec/features/configuration/missing_configuration.rb +0 -14
  48. data/spec/features/folders_spec.rb +0 -36
  49. data/spec/features/helper.rb +0 -2
  50. data/spec/features/local/list_accounts_spec.rb +0 -12
  51. data/spec/features/local/list_emails_spec.rb +0 -21
  52. data/spec/features/local/list_folders_spec.rb +0 -21
  53. data/spec/features/local/show_an_email_spec.rb +0 -34
  54. data/spec/features/migrate_spec.rb +0 -35
  55. data/spec/features/remote/list_account_folders_spec.rb +0 -16
  56. data/spec/features/restore_spec.rb +0 -162
  57. data/spec/features/status_spec.rb +0 -43
  58. data/spec/features/support/aruba.rb +0 -78
  59. data/spec/features/support/backup_directory.rb +0 -43
  60. data/spec/features/support/email_server.rb +0 -110
  61. data/spec/features/support/shared/connection_context.rb +0 -14
  62. data/spec/features/support/shared/message_fixtures.rb +0 -16
  63. data/spec/fixtures/connection.yml +0 -7
  64. data/spec/spec_helper.rb +0 -15
  65. data/spec/support/fixtures.rb +0 -11
  66. data/spec/support/higline_test_helpers.rb +0 -8
  67. data/spec/support/silence_logging.rb +0 -7
  68. data/spec/unit/email/mboxrd/message_spec.rb +0 -177
  69. data/spec/unit/email/provider/apple_mail_spec.rb +0 -7
  70. data/spec/unit/email/provider/base_spec.rb +0 -11
  71. data/spec/unit/email/provider/fastmail_spec.rb +0 -7
  72. data/spec/unit/email/provider/gmail_spec.rb +0 -7
  73. data/spec/unit/email/provider_spec.rb +0 -27
  74. data/spec/unit/imap/backup/account/connection_spec.rb +0 -433
  75. data/spec/unit/imap/backup/account/folder_spec.rb +0 -261
  76. data/spec/unit/imap/backup/account_spec.rb +0 -246
  77. data/spec/unit/imap/backup/cli/accounts_spec.rb +0 -58
  78. data/spec/unit/imap/backup/cli/backup_spec.rb +0 -19
  79. data/spec/unit/imap/backup/cli/folders_spec.rb +0 -39
  80. data/spec/unit/imap/backup/cli/helpers_spec.rb +0 -87
  81. data/spec/unit/imap/backup/cli/local_spec.rb +0 -100
  82. data/spec/unit/imap/backup/cli/migrate_spec.rb +0 -80
  83. data/spec/unit/imap/backup/cli/restore_spec.rb +0 -67
  84. data/spec/unit/imap/backup/cli/setup_spec.rb +0 -17
  85. data/spec/unit/imap/backup/cli/utils_spec.rb +0 -125
  86. data/spec/unit/imap/backup/cli_spec.rb +0 -93
  87. data/spec/unit/imap/backup/client/apple_mail_spec.rb +0 -9
  88. data/spec/unit/imap/backup/client/default_spec.rb +0 -22
  89. data/spec/unit/imap/backup/configuration_spec.rb +0 -238
  90. data/spec/unit/imap/backup/downloader_spec.rb +0 -96
  91. data/spec/unit/imap/backup/logger_spec.rb +0 -48
  92. data/spec/unit/imap/backup/migrator_spec.rb +0 -58
  93. data/spec/unit/imap/backup/sanitizer_spec.rb +0 -42
  94. data/spec/unit/imap/backup/serializer/directory_spec.rb +0 -37
  95. data/spec/unit/imap/backup/serializer/imap_spec.rb +0 -218
  96. data/spec/unit/imap/backup/serializer/mbox_enumerator_spec.rb +0 -45
  97. data/spec/unit/imap/backup/serializer/mbox_spec.rb +0 -101
  98. data/spec/unit/imap/backup/serializer_spec.rb +0 -296
  99. data/spec/unit/imap/backup/setup/account_spec.rb +0 -461
  100. data/spec/unit/imap/backup/setup/asker_spec.rb +0 -137
  101. data/spec/unit/imap/backup/setup/connection_tester_spec.rb +0 -51
  102. data/spec/unit/imap/backup/setup/folder_chooser_spec.rb +0 -146
  103. data/spec/unit/imap/backup/setup/helpers_spec.rb +0 -15
  104. data/spec/unit/imap/backup/setup_spec.rb +0 -301
  105. data/spec/unit/imap/backup/thunderbird/mailbox_exporter_spec.rb +0 -116
  106. data/spec/unit/imap/backup/uploader_spec.rb +0 -54
  107. data/spec/unit/imap/backup/utils_spec.rb +0 -92
  108. data/spec/unit/retry_on_error_spec.rb +0 -34
@@ -1,261 +0,0 @@
1
- # rubocop:disable RSpec/PredicateMatcher
2
-
3
- describe Imap::Backup::Account::Folder do
4
- FOLDER_NAME = "Gelöscht".freeze
5
- ENCODED_FOLDER_NAME = "Gel&APY-scht".freeze
6
-
7
- subject { described_class.new(connection, FOLDER_NAME) }
8
-
9
- let(:client) do
10
- instance_double(
11
- Imap::Backup::Client::Default,
12
- append: append_response,
13
- create: nil,
14
- examine: nil,
15
- expunge: nil,
16
- responses: responses,
17
- select: nil,
18
- uid_store: nil
19
- )
20
- end
21
- let(:connection) do
22
- instance_double(Imap::Backup::Account::Connection, client: client)
23
- end
24
- let(:missing_mailbox_data) do
25
- OpenStruct.new(text: "Unknown Mailbox: #{FOLDER_NAME}")
26
- end
27
- let(:missing_mailbox_response) { OpenStruct.new(data: missing_mailbox_data) }
28
- let(:missing_mailbox_error) do
29
- Net::IMAP::NoResponseError.new(missing_mailbox_response)
30
- end
31
- let(:responses) { [] }
32
- let(:append_response) { nil }
33
- let(:uids) { [5678, 123] }
34
-
35
- before { allow(client).to receive(:uid_search) { uids } }
36
-
37
- describe "#uids" do
38
- it "lists available messages" do
39
- expect(subject.uids).to eq(uids.reverse)
40
- end
41
-
42
- context "with missing mailboxes" do
43
- before do
44
- allow(client).to receive(:examine).
45
- with(ENCODED_FOLDER_NAME).and_raise(missing_mailbox_error)
46
- end
47
-
48
- it "returns an empty array" do
49
- expect(subject.uids).to eq([])
50
- end
51
- end
52
-
53
- context "with no SEARCH response in Net::IMAP" do
54
- let(:no_method_error) do
55
- NoMethodError.new("Somethimes SEARCH responses come out undefined")
56
- end
57
-
58
- before do
59
- allow(client).to receive(:examine).
60
- with(ENCODED_FOLDER_NAME).and_raise(missing_mailbox_error)
61
- end
62
-
63
- it "returns an empty array" do
64
- expect(subject.uids).to eq([])
65
- end
66
- end
67
-
68
- context "when the UID search fails" do
69
- before do
70
- allow(client).to receive(:uid_search).and_raise(NoMethodError)
71
- end
72
-
73
- it "returns an empty array" do
74
- expect(subject.uids).to eq([])
75
- end
76
- end
77
- end
78
-
79
- describe "#fetch_multi" do
80
- let(:message_body) { instance_double(String, force_encoding: nil) }
81
- let(:attributes) { {"UID" => "uid", "BODY[]" => message_body, "other" => "xxx"} }
82
- let(:fetch_data_item) do
83
- instance_double(Net::IMAP::FetchData, attr: attributes)
84
- end
85
-
86
- before { allow(client).to receive(:uid_fetch) { [fetch_data_item] } }
87
-
88
- it "returns the uid and message" do
89
- expect(subject.fetch_multi([123])).to eq([{uid: "uid", body: message_body}])
90
- end
91
-
92
- context "when the server responds with nothing" do
93
- before { allow(client).to receive(:uid_fetch) { nil } }
94
-
95
- it "is nil" do
96
- expect(subject.fetch_multi([123])).to be_nil
97
- end
98
- end
99
-
100
- context "when the mailbox doesn't exist" do
101
- before do
102
- allow(client).to receive(:examine).
103
- with(ENCODED_FOLDER_NAME).and_raise(missing_mailbox_error)
104
- end
105
-
106
- it "is nil" do
107
- expect(subject.fetch_multi([123])).to be_nil
108
- end
109
- end
110
-
111
- context "when the first fetch_uid attempts fail" do
112
- before do
113
- outcomes = [-> { raise EOFError }, -> { [fetch_data_item] }]
114
- allow(client).to receive(:uid_fetch) { outcomes.shift.call }
115
- end
116
-
117
- it "retries" do
118
- subject.fetch_multi([123])
119
-
120
- expect(client).to have_received(:uid_fetch).twice
121
- end
122
-
123
- it "succeeds" do
124
- subject.fetch_multi([123])
125
- end
126
- end
127
- end
128
-
129
- describe "#folder" do
130
- it "is the name" do
131
- expect(subject.folder).to eq(FOLDER_NAME)
132
- end
133
- end
134
-
135
- describe "#exist?" do
136
- context "when the folder exists" do
137
- it "is true" do
138
- expect(subject.exist?).to be_truthy
139
- end
140
- end
141
-
142
- context "when the folder doesn't exist" do
143
- before do
144
- allow(client).to receive(:examine).
145
- with(ENCODED_FOLDER_NAME).and_raise(missing_mailbox_error)
146
- end
147
-
148
- it "is false" do
149
- expect(subject.exist?).to be_falsey
150
- end
151
- end
152
- end
153
-
154
- describe "#create" do
155
- context "when the folder exists" do
156
- it "is does not create the folder" do
157
- expect(client).to_not receive(:create)
158
-
159
- subject.create
160
- end
161
- end
162
-
163
- context "when the folder doesn't exist" do
164
- before do
165
- allow(client).to receive(:examine).
166
- with(ENCODED_FOLDER_NAME).and_raise(missing_mailbox_error)
167
- end
168
-
169
- it "creates the folder" do
170
- expect(client).to receive(:create)
171
-
172
- subject.create
173
- end
174
-
175
- it "encodes the folder name" do
176
- expect(client).to receive(:create).with(ENCODED_FOLDER_NAME)
177
-
178
- subject.create
179
- end
180
- end
181
- end
182
-
183
- describe "#uid_validity" do
184
- let(:responses) { {"UIDVALIDITY" => ["x", "uid validity"]} }
185
-
186
- it "is returned" do
187
- expect(subject.uid_validity).to eq("uid validity")
188
- end
189
-
190
- context "when the folder doesn't exist" do
191
- before do
192
- allow(client).to receive(:examine).
193
- with(ENCODED_FOLDER_NAME).and_raise(missing_mailbox_error)
194
- end
195
-
196
- it "raises an error" do
197
- expect do
198
- subject.uid_validity
199
- end.to raise_error(Imap::Backup::FolderNotFound)
200
- end
201
- end
202
- end
203
-
204
- describe "#append" do
205
- let(:message) do
206
- instance_double(
207
- Email::Mboxrd::Message,
208
- imap_body: "imap body",
209
- date: message_date
210
- )
211
- end
212
- let(:message_date) { Time.new(2010, 10, 10, 9, 15, 22, 0) }
213
- let(:append_response) do
214
- OpenStruct.new(data: OpenStruct.new(code: OpenStruct.new(data: "1 2")))
215
- end
216
-
217
- it "appends the message" do
218
- expect(client).to receive(:append)
219
-
220
- subject.append(message)
221
- end
222
-
223
- it "sets the date and time" do
224
- expect(client).to receive(:append).
225
- with(anything, anything, anything, message_date)
226
-
227
- subject.append(message)
228
- end
229
-
230
- it "returns the new uid" do
231
- expect(subject.append(message)).to eq(2)
232
- end
233
-
234
- it "set the new uid validity" do
235
- subject.append(message)
236
-
237
- expect(subject.uid_validity).to eq(1)
238
- end
239
- end
240
-
241
- describe "#clear" do
242
- before do
243
- subject.clear
244
- end
245
-
246
- it "uses select to have read-write access" do
247
- expect(client).to have_received(:select)
248
- end
249
-
250
- it "marks all emails as deleted" do
251
- expect(client).
252
- to have_received(:uid_store).with(uids.sort, "+FLAGS", [:Deleted])
253
- end
254
-
255
- it "deletes marked emails" do
256
- expect(client).to have_received(:expunge)
257
- end
258
- end
259
- end
260
-
261
- # rubocop:enable RSpec/PredicateMatcher
@@ -1,246 +0,0 @@
1
- module Imap::Backup
2
- describe Account do
3
- subject { described_class.new(options) }
4
-
5
- let(:options) { {username: "user", password: "pwd"} }
6
-
7
- describe "#changes" do
8
- it "lists changes" do
9
- subject.username = "new"
10
-
11
- expect(subject.changes).to eq(username: {from: "user", to: "new"})
12
- end
13
-
14
- context "when more than one change is made" do
15
- it "retains the last one" do
16
- subject.username = "first"
17
- subject.username = "second"
18
-
19
- expect(subject.changes).to eq(username: {from: "user", to: "second"})
20
- end
21
- end
22
-
23
- context "when a value is reset to its original value" do
24
- it "removes the change" do
25
- subject.username = "changed"
26
- subject.username = "user"
27
-
28
- expect(subject.changes).to eq({})
29
- end
30
- end
31
- end
32
-
33
- describe "#connection" do
34
- it "returns a Connection for the Account" do
35
- result = subject.connection
36
-
37
- expect(result).to be_a(Account::Connection)
38
- expect(result.account).to be subject
39
- end
40
- end
41
-
42
- describe "#valid?" do
43
- context "with username and password" do
44
- it "is true" do
45
- expect(subject.valid?).to be true
46
- end
47
- end
48
-
49
- context "without a username" do
50
- let(:options) { {password: "pwd"} }
51
-
52
- it "is false" do
53
- expect(subject.valid?).to be false
54
- end
55
- end
56
-
57
- context "without a password" do
58
- let(:options) { {username: "user"} }
59
-
60
- it "is false" do
61
- expect(subject.valid?).to be false
62
- end
63
- end
64
- end
65
-
66
- describe "#modified?" do
67
- context "with changes" do
68
- it "is true" do
69
- subject.username = "new"
70
-
71
- expect(subject.modified?).to be true
72
- end
73
- end
74
-
75
- context "without changes" do
76
- it "is false" do
77
- expect(subject.modified?).to be false
78
- end
79
- end
80
- end
81
-
82
- describe "#clear_changes" do
83
- it "clears changes" do
84
- subject.username = "new"
85
- subject.clear_changes
86
-
87
- expect(subject.changes).to eq({})
88
- end
89
- end
90
-
91
- describe "#mark_for_deletion" do
92
- it "sets marked_for_deletion" do
93
- subject.mark_for_deletion
94
-
95
- expect(subject.marked_for_deletion?).to be true
96
- end
97
- end
98
-
99
- describe "#marked_for_deletion?" do
100
- it "defaults to false" do
101
- expect(subject.marked_for_deletion?).to be false
102
- end
103
- end
104
-
105
- describe "#to_h" do
106
- it "returns a Hash representation" do
107
- expect(subject.to_h).to eq({username: "user", password: "pwd"})
108
- end
109
-
110
- context "when local_path is set" do
111
- let(:options) { {username: "user", password: "pwd", local_path: "local_path"} }
112
-
113
- it "includes local_path" do
114
- expect(subject.to_h).to include({local_path: "local_path"})
115
- end
116
- end
117
-
118
- context "when folders is set" do
119
- let(:options) { {username: "user", password: "pwd", folders: ["folder"]} }
120
-
121
- it "includes folders" do
122
- expect(subject.to_h).to include({folders: ["folder"]})
123
- end
124
- end
125
-
126
- context "when multi_fetch_size is set" do
127
- let(:options) { {username: "user", password: "pwd", multi_fetch_size: "3"} }
128
-
129
- it "includes multi_fetch_size" do
130
- expect(subject.to_h).to include({multi_fetch_size: 3})
131
- end
132
- end
133
-
134
- context "when server is set" do
135
- let(:options) { {username: "user", password: "pwd", server: "server"} }
136
-
137
- it "includes server" do
138
- expect(subject.to_h).to include({server: "server"})
139
- end
140
- end
141
-
142
- context "when connection_options is set" do
143
- let(:options) { {username: "user", password: "pwd", connection_options: "foo"} }
144
-
145
- it "includes connection_options" do
146
- expect(subject.to_h).to include({connection_options: "foo"})
147
- end
148
- end
149
- end
150
-
151
- describe "#multi_fetch_size" do
152
- let(:options) { {username: "user", password: "pwd", multi_fetch_size: multi_fetch_size} }
153
- let(:multi_fetch_size) { 10 }
154
-
155
- it "returns the initialized value" do
156
- expect(subject.multi_fetch_size).to eq(10)
157
- end
158
-
159
- context "when the initialized value is a string representation of a positive number" do
160
- let(:multi_fetch_size) { "10" }
161
-
162
- it "returns one" do
163
- expect(subject.multi_fetch_size).to eq(10)
164
- end
165
- end
166
-
167
- context "when the initialized value is not a number" do
168
- let(:multi_fetch_size) { "ciao" }
169
-
170
- it "returns one" do
171
- expect(subject.multi_fetch_size).to eq(1)
172
- end
173
- end
174
-
175
- context "when the initialized value is not a positive number" do
176
- let(:multi_fetch_size) { "-99" }
177
-
178
- it "returns one" do
179
- expect(subject.multi_fetch_size).to eq(1)
180
- end
181
- end
182
- end
183
-
184
- [
185
- [:username, "username", "username"],
186
- [:password, "password", "password"],
187
- [:local_path, "local_path", "local_path"],
188
- [:multi_fetch_size, "2", 2],
189
- [:server, "server", "server"],
190
- [:folders, ["folder"], ["folder"]],
191
- [:connection_options, '{"some": "option"}', {"some" => "option"}]
192
- ].each do |attribute, value, expected|
193
- describe "##{attribute}=" do
194
- let(:options) { {} }
195
-
196
- before { subject.send(:"#{attribute}=", value) }
197
-
198
- it "sets the #{attribute}" do
199
- expect(subject.send(attribute)).to eq(expected)
200
- end
201
-
202
- it "adds a change" do
203
- expect(subject.changes).to eq(attribute => {from: nil, to: expected})
204
- end
205
-
206
- if attribute == :folders
207
- context "when the supplied value is not an Array" do
208
- it "fails" do
209
- expect do
210
- subject.folders = "aaa"
211
- end.to raise_error(RuntimeError, /must be an Array/)
212
- end
213
- end
214
- end
215
-
216
- if attribute == :multi_fetch_size
217
- context "when the supplied value is not a number" do
218
- before { subject.multi_fetch_size = "ciao" }
219
-
220
- it "sets multi_fetch_size to one" do
221
- expect(subject.multi_fetch_size).to eq(1)
222
- end
223
- end
224
-
225
- context "when the supplied value is not a positive number" do
226
- before { subject.multi_fetch_size = "-1" }
227
-
228
- it "sets multi_fetch_size to one" do
229
- expect(subject.multi_fetch_size).to eq(1)
230
- end
231
- end
232
- end
233
-
234
- if attribute == :connection_options
235
- context "when the supplied value is not valid JSON" do
236
- it "fails" do
237
- expect do
238
- subject.connection_options = "NOT JSON"
239
- end.to raise_error(JSON::ParserError)
240
- end
241
- end
242
- end
243
- end
244
- end
245
- end
246
- end
@@ -1,58 +0,0 @@
1
- require "imap/backup/cli/accounts"
2
-
3
- describe Imap::Backup::CLI::Accounts do
4
- subject { described_class.new(required_accounts) }
5
-
6
- let(:required_accounts) { [] }
7
- let(:accounts) { [account1, account2] }
8
- let(:account1) do
9
- instance_double(
10
- Imap::Backup::Account,
11
- username: "a1@example.com"
12
- )
13
- end
14
- let(:account2) do
15
- instance_double(
16
- Imap::Backup::Account,
17
- username: "a2@example.com"
18
- )
19
- end
20
- let(:store) do
21
- instance_double(Imap::Backup::Configuration, accounts: accounts)
22
- end
23
- let(:exists) { true }
24
-
25
- before do
26
- allow(Imap::Backup::Configuration).to receive(:new) { store }
27
- allow(Imap::Backup::Configuration).
28
- to receive(:exist?) { exists }
29
- end
30
-
31
- describe "#each" do
32
- specify "calls the block with each account" do
33
- result = subject.map { |a| a }
34
-
35
- expect(result).to eq(accounts)
36
- end
37
-
38
- context "when the configuration file is missing" do
39
- let(:exists) { false }
40
-
41
- it "fails" do
42
- expect do
43
- subject.each {}
44
- end.to raise_error(Imap::Backup::ConfigurationNotFound, /not found/)
45
- end
46
- end
47
-
48
- context "when an account list is provided" do
49
- let(:required_accounts) { %w(a2@example.com) }
50
-
51
- specify "calls the block with each account" do
52
- result = subject.map { |a| a }
53
-
54
- expect(result).to eq([account2])
55
- end
56
- end
57
- end
58
- end
@@ -1,19 +0,0 @@
1
- module Imap::Backup
2
- describe CLI::Backup do
3
- subject { described_class.new({}) }
4
-
5
- let(:connection) { instance_double(Account::Connection, run_backup: nil) }
6
-
7
- before do
8
- # rubocop:disable RSpec/SubjectStub
9
- allow(subject).to receive(:each_connection).with([]).and_yield(connection)
10
- # rubocop:enable RSpec/SubjectStub
11
- end
12
-
13
- it "runs the backup for each connection" do
14
- subject.run
15
-
16
- expect(connection).to have_received(:run_backup)
17
- end
18
- end
19
- end
@@ -1,39 +0,0 @@
1
- module Imap::Backup
2
- describe CLI::Folders do
3
- subject { described_class.new({}) }
4
-
5
- let(:connection) do
6
- instance_double(
7
- Account::Connection, account: account, folder_names: folder_names
8
- )
9
- end
10
- let(:account) { instance_double(Account, username: "user") }
11
- let(:folder_names) { ["my-folder"] }
12
-
13
- before do
14
- allow(Kernel).to receive(:puts)
15
- allow(Kernel).to receive(:warn)
16
- # rubocop:disable RSpec/SubjectStub
17
- allow(subject).to receive(:each_connection).with([]).and_yield(connection)
18
- # rubocop:enable RSpec/SubjectStub
19
-
20
- subject.run
21
- end
22
-
23
- it "lists folders" do
24
- expect(Kernel).to have_received(:puts).with("\tmy-folder")
25
- end
26
-
27
- context "when the folder list is not fetched" do
28
- let(:folder_names) { nil }
29
-
30
- it "warns" do
31
- expect(Kernel).to have_received(:warn).with(/Unable to list/)
32
- end
33
-
34
- it "doesn't fail" do
35
- subject.run
36
- end
37
- end
38
- end
39
- end
@@ -1,87 +0,0 @@
1
- require "imap/backup/cli/helpers"
2
-
3
- module Imap::Backup
4
- class WithHelpers
5
- include CLI::Helpers
6
- end
7
-
8
- RSpec.describe CLI::Helpers do
9
- subject { WithHelpers.new }
10
-
11
- let(:accounts) { instance_double(CLI::Accounts) }
12
- let(:email) { "email@example.com" }
13
- let(:account1) { instance_double(Account, username: email, connection: "c1") }
14
- let(:account2) { instance_double(Account, username: "foo", connection: "c2") }
15
- let(:items) { [account1, account2] }
16
-
17
- before do
18
- allow(CLI::Accounts).to receive(:new) { accounts }
19
- allow(accounts).to receive(:each).
20
- and_yield(account1).
21
- and_yield(account2)
22
- allow(accounts).to receive(:find) do |&block|
23
- items.find { |a| block.call(a) }
24
- end
25
- end
26
-
27
- describe ".symbolized" do
28
- let(:arguments) { {"foo" => 1, "bar" => 2} }
29
- let(:result) { subject.symbolized(arguments) }
30
-
31
- it "converts string keys to symbols" do
32
- expect(result.keys).to eq([:foo, :bar])
33
- end
34
-
35
- context "when keys have hyphens" do
36
- let(:arguments) { {"some-option"=> 3} }
37
-
38
- it "replaces them with underscores" do
39
- expect(result.keys).to eq([:some_option])
40
- end
41
- end
42
- end
43
-
44
- describe ".account" do
45
- it "returns any account with a matching username" do
46
- expect(subject.account(email)).to eq(account1)
47
- end
48
-
49
- context "when no match is found" do
50
- let(:items) { [account2] }
51
- it "fails" do
52
- expect do
53
- subject.account(email)
54
- end.to raise_error(RuntimeError, /not a configured account/)
55
- end
56
- end
57
- end
58
-
59
- describe ".connection" do
60
- it "returns the connection for any account with a matching username" do
61
- result = subject.connection(email)
62
- expect(result).to be_a(Account::Connection)
63
- expect(result.account).to eq(account1)
64
- end
65
- end
66
-
67
- describe ".each_connection" do
68
- it "yields each connection" do
69
- expect { |b| subject.each_connection([email, "foo"], &b) }.
70
- to yield_successive_args("c1", "c2")
71
- end
72
-
73
- context "when there is no configuration" do
74
- before do
75
- allow(accounts).to receive(:each).
76
- and_raise(Imap::Backup::ConfigurationNotFound)
77
- end
78
-
79
- it "fails" do
80
- expect do
81
- subject.each_connection([email])
82
- end.to raise_error(RuntimeError, /not configured/)
83
- end
84
- end
85
- end
86
- end
87
- end