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.
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