imap-backup 5.2.0 → 6.0.1

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 (102) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +9 -2
  3. data/docs/development.md +10 -4
  4. data/imap-backup.gemspec +5 -1
  5. data/lib/cli_coverage.rb +11 -11
  6. data/lib/email/provider/base.rb +2 -0
  7. data/lib/email/provider/unknown.rb +2 -0
  8. data/lib/email/provider.rb +2 -0
  9. data/lib/imap/backup/account/connection/backup_folders.rb +27 -0
  10. data/lib/imap/backup/account/connection/client_factory.rb +54 -0
  11. data/lib/imap/backup/account/connection/folder_names.rb +26 -0
  12. data/lib/imap/backup/account/connection.rb +17 -105
  13. data/lib/imap/backup/account/folder.rb +9 -6
  14. data/lib/imap/backup/account.rb +36 -16
  15. data/lib/imap/backup/cli/backup.rb +1 -3
  16. data/lib/imap/backup/cli/folders.rb +3 -3
  17. data/lib/imap/backup/cli/helpers.rb +24 -22
  18. data/lib/imap/backup/cli/local.rb +20 -13
  19. data/lib/imap/backup/cli/migrate.rb +5 -11
  20. data/lib/imap/backup/cli/restore.rb +8 -7
  21. data/lib/imap/backup/cli/setup.rb +10 -8
  22. data/lib/imap/backup/cli/stats.rb +78 -0
  23. data/lib/imap/backup/cli/status.rb +2 -2
  24. data/lib/imap/backup/cli/utils.rb +6 -8
  25. data/lib/imap/backup/cli.rb +24 -3
  26. data/lib/imap/backup/configuration.rb +9 -21
  27. data/lib/imap/backup/downloader.rb +56 -34
  28. data/lib/imap/backup/migrator.rb +5 -5
  29. data/lib/imap/backup/sanitizer.rb +3 -2
  30. data/lib/imap/backup/serializer/appender.rb +49 -0
  31. data/lib/imap/backup/serializer/directory.rb +37 -0
  32. data/lib/imap/backup/serializer/imap.rb +144 -0
  33. data/lib/imap/backup/serializer/mbox.rb +33 -88
  34. data/lib/imap/backup/serializer/mbox_enumerator.rb +2 -0
  35. data/lib/imap/backup/serializer/message_enumerator.rb +29 -0
  36. data/lib/imap/backup/serializer/unused_name_finder.rb +25 -0
  37. data/lib/imap/backup/serializer.rb +160 -3
  38. data/lib/imap/backup/setup/account/header.rb +75 -0
  39. data/lib/imap/backup/setup/account.rb +41 -95
  40. data/lib/imap/backup/setup/asker.rb +4 -15
  41. data/lib/imap/backup/setup/backup_path.rb +41 -0
  42. data/lib/imap/backup/setup/email.rb +45 -0
  43. data/lib/imap/backup/setup/folder_chooser.rb +3 -3
  44. data/lib/imap/backup/setup/helpers.rb +2 -2
  45. data/lib/imap/backup/setup.rb +5 -4
  46. data/lib/imap/backup/thunderbird/mailbox_exporter.rb +41 -22
  47. data/lib/imap/backup/uploader.rb +46 -8
  48. data/lib/imap/backup/utils.rb +1 -1
  49. data/lib/imap/backup/version.rb +3 -3
  50. data/lib/imap/backup.rb +0 -2
  51. metadata +31 -105
  52. data/lib/imap/backup/serializer/mbox_store.rb +0 -217
  53. data/spec/features/backup_spec.rb +0 -108
  54. data/spec/features/configuration/minimal_configuration.rb +0 -15
  55. data/spec/features/configuration/missing_configuration.rb +0 -14
  56. data/spec/features/folders_spec.rb +0 -36
  57. data/spec/features/helper.rb +0 -2
  58. data/spec/features/local/list_accounts_spec.rb +0 -12
  59. data/spec/features/local/list_emails_spec.rb +0 -21
  60. data/spec/features/local/list_folders_spec.rb +0 -21
  61. data/spec/features/local/show_an_email_spec.rb +0 -34
  62. data/spec/features/migrate_spec.rb +0 -35
  63. data/spec/features/remote/list_account_folders_spec.rb +0 -16
  64. data/spec/features/restore_spec.rb +0 -162
  65. data/spec/features/status_spec.rb +0 -43
  66. data/spec/features/support/aruba.rb +0 -77
  67. data/spec/features/support/backup_directory.rb +0 -43
  68. data/spec/features/support/email_server.rb +0 -110
  69. data/spec/features/support/shared/connection_context.rb +0 -14
  70. data/spec/features/support/shared/message_fixtures.rb +0 -16
  71. data/spec/fixtures/connection.yml +0 -7
  72. data/spec/spec_helper.rb +0 -15
  73. data/spec/support/fixtures.rb +0 -11
  74. data/spec/support/higline_test_helpers.rb +0 -8
  75. data/spec/support/silence_logging.rb +0 -7
  76. data/spec/unit/email/mboxrd/message_spec.rb +0 -177
  77. data/spec/unit/email/provider/apple_mail_spec.rb +0 -7
  78. data/spec/unit/email/provider/base_spec.rb +0 -11
  79. data/spec/unit/email/provider/fastmail_spec.rb +0 -7
  80. data/spec/unit/email/provider/gmail_spec.rb +0 -7
  81. data/spec/unit/email/provider_spec.rb +0 -27
  82. data/spec/unit/imap/backup/account/connection_spec.rb +0 -405
  83. data/spec/unit/imap/backup/account/folder_spec.rb +0 -251
  84. data/spec/unit/imap/backup/cli/accounts_spec.rb +0 -47
  85. data/spec/unit/imap/backup/cli/helpers_spec.rb +0 -87
  86. data/spec/unit/imap/backup/cli/local_spec.rb +0 -81
  87. data/spec/unit/imap/backup/cli/utils_spec.rb +0 -62
  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 -44
  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/serializer/mbox_enumerator_spec.rb +0 -45
  94. data/spec/unit/imap/backup/serializer/mbox_spec.rb +0 -222
  95. data/spec/unit/imap/backup/serializer/mbox_store_spec.rb +0 -329
  96. data/spec/unit/imap/backup/setup/account_spec.rb +0 -366
  97. data/spec/unit/imap/backup/setup/asker_spec.rb +0 -137
  98. data/spec/unit/imap/backup/setup/connection_tester_spec.rb +0 -51
  99. data/spec/unit/imap/backup/setup/folder_chooser_spec.rb +0 -146
  100. data/spec/unit/imap/backup/setup_spec.rb +0 -301
  101. data/spec/unit/imap/backup/uploader_spec.rb +0 -54
  102. data/spec/unit/imap/backup/utils_spec.rb +0 -92
@@ -1,329 +0,0 @@
1
- describe Imap::Backup::Serializer::MboxStore do
2
- subject { described_class.new(base_path, folder) }
3
-
4
- let(:base_path) { "/base/path" }
5
- let(:folder) { "the/folder" }
6
- let(:folder_path) { File.join(base_path, folder) }
7
- let(:imap_pathname) { "#{folder_path}.imap" }
8
- let(:imap_exists) { true }
9
- let(:imap_file) { instance_double(File, write: nil, close: nil) }
10
- let(:mbox_pathname) { "#{folder_path}.mbox" }
11
- let(:mbox_exists) { true }
12
- let(:mbox_file) { instance_double(File, write: nil, close: nil) }
13
- let(:uids) { [3, 2, 1] }
14
- let(:imap_content) do
15
- {
16
- version: Imap::Backup::Serializer::MboxStore::CURRENT_VERSION,
17
- uid_validity: uid_validity,
18
- uids: uids
19
- }.to_json
20
- end
21
- let(:uid_validity) { 123 }
22
-
23
- before do
24
- allow(File).to receive(:exist?).and_call_original
25
- allow(File).to receive(:exist?).with(imap_pathname) { imap_exists }
26
- allow(File).to receive(:exist?).with(mbox_pathname) { mbox_exists }
27
-
28
- allow(File).to receive(:open).and_call_original
29
- allow(File).
30
- to receive(:open).with("/base/path/my/folder.imap") { imap_content }
31
- allow(File).to receive(:open).with(imap_pathname, "w").and_yield(imap_file)
32
- allow(File).to receive(:open).with(mbox_pathname, "w").and_yield(mbox_file)
33
-
34
- allow(File).to receive(:read).and_call_original
35
- allow(File).to receive(:read).with(imap_pathname) { imap_content }
36
-
37
- allow(File).to receive(:unlink).and_call_original
38
- allow(File).to receive(:unlink).with(imap_pathname)
39
- allow(File).to receive(:unlink).with(mbox_pathname)
40
-
41
- allow(FileUtils).to receive(:chmod)
42
- end
43
-
44
- describe "#uid_validity=" do
45
- let(:new_uid_validity) { "13" }
46
- let(:updated_imap_content) do
47
- {
48
- version: Imap::Backup::Serializer::MboxStore::CURRENT_VERSION,
49
- uid_validity: new_uid_validity,
50
- uids: uids
51
- }.to_json
52
- end
53
-
54
- it "sets uid_validity" do
55
- subject.uid_validity = new_uid_validity
56
-
57
- expect(subject.uid_validity).to eq(new_uid_validity)
58
- end
59
-
60
- it "writes the imap file" do
61
- expect(imap_file).to receive(:write).with(updated_imap_content)
62
-
63
- subject.uid_validity = new_uid_validity
64
- end
65
- end
66
-
67
- describe "#uids" do
68
- it "returns the backed-up uids as integers" do
69
- expect(subject.uids).to eq(uids.map(&:to_i))
70
- end
71
-
72
- context "when the imap file does not exist" do
73
- let(:imap_exists) { false }
74
-
75
- it "returns an empty Array" do
76
- expect(subject.uids).to eq([])
77
- end
78
- end
79
-
80
- context "when the imap file is malformed" do
81
- before do
82
- allow(JSON).to receive(:parse).and_raise(JSON::ParserError)
83
- end
84
-
85
- it "returns an empty Array" do
86
- expect(subject.uids).to eq([])
87
- end
88
-
89
- it "deletes the imap file" do
90
- expect(File).to receive(:unlink).with(imap_pathname)
91
-
92
- subject.uids
93
- end
94
-
95
- it "deletes the mbox file" do
96
- expect(File).to receive(:unlink).with(mbox_pathname)
97
-
98
- subject.uids
99
- end
100
-
101
- it "writes a blank mbox file" do
102
- expect(mbox_file).to receive(:write).with("")
103
-
104
- subject.uids
105
- end
106
- end
107
-
108
- context "when the mbox does not exist" do
109
- let(:mbox_exists) { false }
110
-
111
- it "returns an empty Array" do
112
- expect(subject.uids).to eq([])
113
- end
114
- end
115
- end
116
-
117
- describe "#add" do
118
- let(:mbox_formatted_message) { "message in mbox format" }
119
- let(:message_uid) { "999" }
120
- let(:message) do
121
- instance_double(
122
- Email::Mboxrd::Message,
123
- to_serialized: mbox_formatted_message
124
- )
125
- end
126
- let(:updated_imap_content) do
127
- {
128
- version: Imap::Backup::Serializer::MboxStore::CURRENT_VERSION,
129
- uid_validity: uid_validity,
130
- uids: uids + [999]
131
- }.to_json
132
- end
133
-
134
- before do
135
- allow(Email::Mboxrd::Message).to receive(:new) { message }
136
- allow(File).to receive(:open).with(mbox_pathname, "ab") { mbox_file }
137
- end
138
-
139
- it "saves the message to the mbox" do
140
- expect(mbox_file).to receive(:write).with(mbox_formatted_message)
141
-
142
- subject.add(message_uid, "The\nemail\n")
143
- end
144
-
145
- it "saves the uid to the imap file" do
146
- expect(imap_file).to receive(:write).with(updated_imap_content)
147
-
148
- subject.add(message_uid, "The\nemail\n")
149
- end
150
-
151
- context "when the message is already downloaded" do
152
- let(:uids) { [999] }
153
-
154
- it "skips the message" do
155
- expect(mbox_file).to_not receive(:write)
156
-
157
- subject.add(message_uid, "The\nemail\n")
158
- end
159
- end
160
-
161
- context "when the message causes parsing errors" do
162
- before do
163
- allow(message).to receive(:to_serialized).and_raise(ArgumentError)
164
- end
165
-
166
- it "skips the message" do
167
- expect(mbox_file).to_not receive(:write)
168
-
169
- subject.add(message_uid, "The\nemail\n")
170
- end
171
-
172
- it "does not fail" do
173
- expect do
174
- subject.add(message_uid, "The\nemail\n")
175
- end.to_not raise_error
176
- end
177
- end
178
- end
179
-
180
- describe "#load" do
181
- let(:uid) { "1" }
182
- let(:enumerator) do
183
- instance_double(Imap::Backup::Serializer::MboxEnumerator)
184
- end
185
- let(:enumeration) { instance_double(Enumerator) }
186
-
187
- before do
188
- allow(Imap::Backup::Serializer::MboxEnumerator).
189
- to receive(:new) { enumerator }
190
- allow(enumerator).to receive(:each) { enumeration }
191
- allow(enumeration).
192
- to receive(:with_index).
193
- and_yield("", 0).
194
- and_yield("", 1).
195
- and_yield("ciao", 2)
196
- end
197
-
198
- it "returns the message" do
199
- expect(subject.load(uid).supplied_body).to eq("ciao")
200
- end
201
-
202
- context "when the UID is unknown" do
203
- let(:uid) { "99" }
204
-
205
- it "returns nil" do
206
- expect(subject.load(uid)).to be_nil
207
- end
208
- end
209
- end
210
-
211
- describe "#each_message" do
212
- let(:enumerator) do
213
- instance_double(Imap::Backup::Serializer::MboxEnumerator)
214
- end
215
- let(:enumeration) { instance_double(Enumerator) }
216
-
217
- before do
218
- allow(Imap::Backup::Serializer::MboxEnumerator).
219
- to receive(:new) { enumerator }
220
- allow(enumerator).to receive(:each) { enumeration }
221
- allow(enumeration).
222
- to receive(:with_index).
223
- and_yield("", 0).
224
- and_yield("", 1).
225
- and_yield("ciao", 2)
226
- end
227
-
228
- it "yields messages" do
229
- expect { |b| subject.each_message([1], &b) }.
230
- to yield_successive_args([1, instance_of(Email::Mboxrd::Message)])
231
- end
232
-
233
- it "yields the requested message uid" do
234
- subject.each_message([1]) do |uid, _message|
235
- expect(uid).to eq(1)
236
- end
237
- end
238
-
239
- it "yields the requested message" do
240
- subject.each_message([1]) do |_uid, message|
241
- expect(message.supplied_body).to eq("ciao")
242
- end
243
- end
244
-
245
- context "without a block" do
246
- it "returns an Enumerator" do
247
- expect(subject.each_message([1])).to be_a(Enumerator)
248
- end
249
- end
250
- end
251
-
252
- describe "#update_uid" do
253
- let(:old_uid) { "2" }
254
- let(:updated_imap_content) do
255
- {
256
- version: Imap::Backup::Serializer::MboxStore::CURRENT_VERSION,
257
- uid_validity: uid_validity,
258
- uids: [3, 999, 1]
259
- }.to_json
260
- end
261
-
262
- it "updates the stored UID" do
263
- expect(imap_file).to receive(:write).with(updated_imap_content)
264
-
265
- subject.update_uid(old_uid, "999")
266
- end
267
-
268
- context "when the UID is unknown" do
269
- let(:old_uid) { "42" }
270
-
271
- it "does nothing" do
272
- expect(imap_file).to_not receive(:write)
273
-
274
- subject.update_uid(old_uid, "999")
275
- end
276
- end
277
- end
278
-
279
- describe "#reset" do
280
- it "deletes the imap file" do
281
- expect(File).to receive(:unlink).with(imap_pathname)
282
-
283
- subject.reset
284
- end
285
-
286
- it "deletes the mbox file" do
287
- expect(File).to receive(:unlink).with(mbox_pathname)
288
-
289
- subject.reset
290
- end
291
-
292
- it "writes a blank mbox file" do
293
- expect(mbox_file).to receive(:write).with("")
294
-
295
- subject.reset
296
- end
297
- end
298
-
299
- describe "#rename" do
300
- let(:new_name) { "new_name" }
301
- let(:new_folder_path) { File.join(base_path, new_name) }
302
- let(:new_imap_name) { "#{new_folder_path}.imap" }
303
- let(:new_mbox_name) { "#{new_folder_path}.mbox" }
304
-
305
- before do
306
- allow(File).to receive(:rename).and_call_original
307
- allow(File).to receive(:rename).with(imap_pathname, new_imap_name)
308
- allow(File).to receive(:rename).with(mbox_pathname, new_mbox_name)
309
- end
310
-
311
- it "renames the imap file" do
312
- expect(File).to receive(:rename).with(imap_pathname, new_imap_name)
313
-
314
- subject.rename(new_name)
315
- end
316
-
317
- it "renames the mbox file" do
318
- expect(File).to receive(:rename).with(mbox_pathname, new_mbox_name)
319
-
320
- subject.rename(new_name)
321
- end
322
-
323
- it "updates the folder name" do
324
- subject.rename(new_name)
325
-
326
- expect(subject.folder).to eq(new_name)
327
- end
328
- end
329
- end
@@ -1,366 +0,0 @@
1
- describe Imap::Backup::Setup::Account do
2
- ACCOUNT = "account".freeze
3
- GMAIL_IMAP_SERVER = "imap.gmail.com".freeze
4
- HIGHLINE = "highline".freeze
5
- CONFIG = "config".freeze
6
-
7
- subject { described_class.new(config, account, highline) }
8
-
9
- let(:account) do
10
- instance_double(
11
- Imap::Backup::Account,
12
- username: existing_email,
13
- password: existing_password,
14
- server: current_server,
15
- connection_options: nil,
16
- local_path: "/backup/path",
17
- folders: [{name: "my_folder"}],
18
- modified?: false
19
- )
20
- end
21
- let(:account1) do
22
- instance_double(
23
- Imap::Backup::Account,
24
- username: other_email,
25
- local_path: other_existing_path
26
- )
27
- end
28
- let(:accounts) { [account, account1] }
29
- let(:existing_email) { "user@example.com" }
30
- let(:new_email) { "foo@example.com" }
31
- let(:current_server) { "imap.example.com" }
32
- let(:existing_password) { "password" }
33
- let(:other_email) { "other@example.com" }
34
- let(:other_existing_path) { "/other/existing/path" }
35
-
36
- let(:highline) { HIGHLINE }
37
- let(:config) { CONFIG }
38
-
39
- describe "#initialize" do
40
- [:config, :account, :highline].each do |param|
41
- it "expects #{param}" do
42
- expect(subject.send(param)).to eq(send(param))
43
- end
44
- end
45
- end
46
-
47
- describe "#run" do
48
- let(:highline_menu_class) do
49
- Class.new do
50
- attr_reader :choices
51
- attr_accessor :header
52
-
53
- def initialize
54
- @choices = {}
55
- end
56
-
57
- def choice(name, &block)
58
- choices[name] = block
59
- end
60
-
61
- def hidden(name, &block)
62
- choices[name] = block
63
- end
64
- end
65
- end
66
-
67
- let(:highline) { instance_double(HighLine) }
68
- let(:menu) { highline_menu_class.new }
69
- let(:config) do
70
- instance_double(Imap::Backup::Configuration, accounts: accounts)
71
- end
72
-
73
- before do
74
- allow(Kernel).to receive(:system)
75
- allow(Kernel).to receive(:puts)
76
- allow(highline).to receive(:choose) do |&block|
77
- block.call(menu)
78
- throw :done
79
- end
80
- end
81
-
82
- describe "preparation" do
83
- it "clears the screen" do
84
- expect(Kernel).to receive(:system).with("clear")
85
-
86
- subject.run
87
- end
88
-
89
- describe "menu" do
90
- it "shows the menu" do
91
- expect(highline).to receive(:choose)
92
-
93
- subject.run
94
- end
95
- end
96
- end
97
-
98
- describe "menu" do
99
- [
100
- "modify email",
101
- "modify password",
102
- "modify server",
103
- "modify backup path",
104
- "choose backup folders",
105
- "test connection",
106
- "delete",
107
- "(q) return to main menu",
108
- "quit" # TODO: quit is hidden
109
- ].each do |item|
110
- before { subject.run }
111
-
112
- it "has a '#{item}' item" do
113
- expect(menu.choices).to include(item)
114
- end
115
- end
116
- end
117
-
118
- describe "account details" do
119
- [
120
- ["email", /email\s+user@example.com/],
121
- ["password", /password\s+x+/],
122
- ["path", %r(path\s+/backup/path)],
123
- ["folders", /folders\s+my_folder/],
124
- ["server", /server\s+imap.example.com/]
125
- ].each do |attribute, value|
126
- before { subject.run }
127
-
128
- it "shows the #{attribute}" do
129
- expect(menu.header).to match(value)
130
- end
131
- end
132
-
133
- context "with no password" do
134
- let(:existing_password) { "" }
135
-
136
- before { subject.run }
137
-
138
- it "indicates that a password is not set" do
139
- expect(menu.header).to include("password (unset)")
140
- end
141
- end
142
- end
143
-
144
- describe "choosing 'modify email'" do
145
- before do
146
- allow(account).to receive(:"username=")
147
- allow(account).to receive(:"server=")
148
- allow(Imap::Backup::Setup::Asker).
149
- to receive(:email) { new_email }
150
- subject.run
151
- menu.choices["modify email"].call
152
- end
153
-
154
- context "when the server is blank" do
155
- [
156
- ["GMail", "foo@gmail.com", GMAIL_IMAP_SERVER],
157
- ["Fastmail", "bar@fastmail.fm", "imap.fastmail.com"],
158
- ["Fastmail", "bar@fastmail.com", "imap.fastmail.com"]
159
- ].each do |service, email, expected|
160
- context service do
161
- let(:new_email) { email }
162
-
163
- context "with nil" do
164
- let(:current_server) { nil }
165
-
166
- it "sets a default server" do
167
- expect(account).to have_received(:"server=").with(expected)
168
- end
169
- end
170
-
171
- context "with an empty string" do
172
- let(:current_server) { "" }
173
-
174
- it "sets a default server" do
175
- expect(account).to have_received(:"server=").with(expected)
176
- end
177
- end
178
- end
179
- end
180
-
181
- context "when the domain is unrecognized" do
182
- let(:current_server) { nil }
183
- let(:provider) do
184
- instance_double(Email::Provider, provider: :default)
185
- end
186
-
187
- before do
188
- allow(Email::Provider).to receive(:for_address) { provider }
189
- end
190
-
191
- it "does not set a default server" do
192
- expect(account).to_not have_received(:"server=")
193
- end
194
- end
195
- end
196
-
197
- context "when the email is new" do
198
- it "modifies the email address" do
199
- expect(account).to have_received(:"username=").with(new_email)
200
- end
201
- end
202
-
203
- context "when the email already exists" do
204
- let(:new_email) { other_email }
205
-
206
- it "indicates the error" do
207
- expect(Kernel).to have_received(:puts).
208
- with("There is already an account set up with that email address")
209
- end
210
-
211
- it "doesn't set the email" do
212
- expect(account.username).to eq(existing_email)
213
- end
214
- end
215
- end
216
-
217
- describe "choosing 'modify password'" do
218
- let(:new_password) { "new_password" }
219
-
220
- before do
221
- allow(account).to receive(:"password=")
222
- allow(Imap::Backup::Setup::Asker).
223
- to receive(:password) { new_password }
224
- subject.run
225
- menu.choices["modify password"].call
226
- end
227
-
228
- context "when the user enters a password" do
229
- it "updates the password" do
230
- expect(account).to have_received(:"password=").with(new_password)
231
- end
232
- end
233
-
234
- context "when the user cancels" do
235
- let(:new_password) { nil }
236
-
237
- it "does nothing" do
238
- expect(account.password).to eq(existing_password)
239
- end
240
- end
241
- end
242
-
243
- describe "choosing 'modify server'" do
244
- let(:server) { "server" }
245
-
246
- before do
247
- allow(account).to receive(:"server=")
248
- allow(highline).to receive(:ask).with("server: ") { server }
249
-
250
- subject.run
251
-
252
- menu.choices["modify server"].call
253
- end
254
-
255
- it "updates the server" do
256
- expect(account).to have_received(:"server=").with(server)
257
- end
258
- end
259
-
260
- describe "choosing 'modify backup path'" do
261
- let(:new_backup_path) { "/new/path" }
262
-
263
- before do
264
- allow(account).to receive(:"local_path=")
265
- @validator = nil
266
- allow(
267
- Imap::Backup::Setup::Asker
268
- ).to receive(:backup_path) do |_path, validator|
269
- @validator = validator
270
- new_backup_path
271
- end
272
- subject.run
273
- menu.choices["modify backup path"].call
274
- end
275
-
276
- it "updates the path" do
277
- expect(account).to have_received(:"local_path=").with(new_backup_path)
278
- end
279
-
280
- context "when the path is not used by other backups" do
281
- it "is accepts it" do
282
- # rubocop:disable RSpec/InstanceVariable
283
- expect(@validator.call("/unknown/path")).to be_truthy
284
- # rubocop:enable RSpec/InstanceVariable
285
- end
286
- end
287
-
288
- context "when the path is used by other backups" do
289
- it "fails validation" do
290
- # rubocop:disable RSpec/InstanceVariable
291
- expect(@validator.call(other_existing_path)).to be_falsey
292
- # rubocop:enable RSpec/InstanceVariable
293
- end
294
- end
295
- end
296
-
297
- describe "choosing 'choose backup folders'" do
298
- let(:chooser) do
299
- instance_double(Imap::Backup::Setup::FolderChooser, run: nil)
300
- end
301
-
302
- before do
303
- allow(Imap::Backup::Setup::FolderChooser).
304
- to receive(:new) { chooser }
305
- subject.run
306
- menu.choices["choose backup folders"].call
307
- end
308
-
309
- it "edits folders" do
310
- expect(chooser).to have_received(:run)
311
- end
312
- end
313
-
314
- describe "choosing 'test connection'" do
315
- let(:connection_tester) do
316
- instance_double(
317
- Imap::Backup::Setup::ConnectionTester,
318
- test: "All fine"
319
- )
320
- end
321
-
322
- before do
323
- allow(Imap::Backup::Setup::ConnectionTester).
324
- to receive(:new) { connection_tester }
325
- allow(highline).to receive(:ask)
326
- subject.run
327
- menu.choices["test connection"].call
328
- end
329
-
330
- it "tests the connection" do
331
- expect(connection_tester).to have_received(:test)
332
- end
333
- end
334
-
335
- describe "choosing 'delete'" do
336
- let(:confirmed) { true }
337
-
338
- before do
339
- allow(account).to receive(:mark_for_deletion!)
340
- allow(highline).to receive(:agree) { confirmed }
341
- subject.run
342
- catch :done do
343
- menu.choices["delete"].call
344
- end
345
- end
346
-
347
- it "asks for confirmation" do
348
- expect(highline).to have_received(:agree)
349
- end
350
-
351
- context "when the user confirms deletion" do
352
- it "flags the account to be deleted" do
353
- expect(account).to have_received(:mark_for_deletion!)
354
- end
355
- end
356
-
357
- context "without confirmation" do
358
- let(:confirmed) { false }
359
-
360
- it "doesn't flag the account to be deleted" do
361
- expect(account).to_not have_received(:mark_for_deletion!)
362
- end
363
- end
364
- end
365
- end
366
- end