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,177 +0,0 @@
1
- msg_no_from = <<~NO_FROM
2
- Delivered-To: you@example.com
3
- From: example <www.example.com>
4
- To: FirstName LastName <you@example.com>
5
- Subject: Re: no subject
6
- NO_FROM
7
-
8
- msg_bad_from = <<~BAD_FROM
9
- Delivered-To: you@example.com
10
- from: "FirstName LastName (TEXT)" <"TEXT*" <no-reply@example.com>>
11
- To: FirstName LastName <you@example.com>
12
- Subject: Re: no subject
13
- BAD_FROM
14
-
15
- msg_no_from_but_return_path = <<~RETURN_PATH
16
- Delivered-To: you@example.com
17
- From: example <www.example.com>
18
- To: FirstName LastName <you@example.com>
19
- Return-Path: <me@example.com>
20
- Subject: Re: no subject
21
- RETURN_PATH
22
-
23
- msg_no_from_but_sender = <<~NOT_SENDER
24
- Delivered-To: you@example.com
25
- To: FirstName LastName <you@example.com>
26
- Subject: Re: no subject
27
- Sender: FistName LastName <me@example.com>
28
- NOT_SENDER
29
-
30
- describe Email::Mboxrd::Message do
31
- subject { described_class.new(message_body) }
32
-
33
- let(:from) { "me@example.com" }
34
- let(:date) { DateTime.new(2012, 12, 13, 18, 23, 45) }
35
- let(:message_body) do
36
- instance_double(String, clone: cloned_message_body, force_encoding: nil)
37
- end
38
- let(:cloned_message_body) do
39
- "Foo\nBar\nFrom at the beginning of the line\n>>From quoted"
40
- end
41
- let(:msg_good) do
42
- <<~GOOD
43
- Delivered-To: you@example.com
44
- From: Foo <foo@example.com>
45
- To: FirstName LastName <you@example.com>
46
- Date: #{date.rfc822}
47
- Subject: Re: no subject
48
- GOOD
49
- end
50
-
51
- let(:msg_bad_date) do
52
- <<~BAD
53
- Delivered-To: you@example.com
54
- From: Foo <foo@example.com>
55
- To: FirstName LastName <you@example.com>
56
- Date: Mon,5 May 2014 08:97:99 GMT
57
- Subject: Re: no subject
58
- BAD
59
- end
60
-
61
- describe ".from_serialized" do
62
- let(:serialized_message) { "From foo@a.com\n#{imap_message}" }
63
- let(:imap_message) { "Delivered-To: me@example.com\nFrom Me\n" }
64
- let!(:result) { described_class.from_serialized(serialized_message) }
65
-
66
- it "returns the message" do
67
- expect(result).to be_a(described_class)
68
- end
69
-
70
- it "removes one level of > before From" do
71
- expect(result.supplied_body).to eq(imap_message)
72
- end
73
- end
74
-
75
- describe "#to_serialized" do
76
- let(:mail) { instance_double(Mail::Message, from: [from], date: date) }
77
-
78
- before do
79
- allow(Mail).to receive(:new).with(cloned_message_body) { mail }
80
- end
81
-
82
- it "adds a 'From ' line at the start" do
83
- expected = "From #{from} #{date.asctime}\n"
84
- expect(subject.to_serialized).to start_with(expected)
85
- end
86
-
87
- it "replaces existing 'From ' with '>From '" do
88
- expect(subject.to_serialized).to include("\n>From at the beginning")
89
- end
90
-
91
- it "appends > before '>+From '" do
92
- expect(subject.to_serialized).to include("\n>>>From quoted")
93
- end
94
-
95
- context "when date is missing" do
96
- let(:date) { nil }
97
-
98
- it "does no fail" do
99
- expect { subject.to_serialized }.to_not raise_error
100
- end
101
- end
102
- end
103
-
104
- describe "From" do
105
- before do
106
- # call original for these tests because we want to test the behaviour of
107
- # class-under-test given different behaviour of the Mail parser
108
- allow(Mail).to receive(:new).and_call_original
109
- end
110
-
111
- context "when original message 'from' is missing" do
112
- let(:message_body) { msg_no_from }
113
-
114
- it "'from' is empty string" do
115
- expect(subject.to_serialized).to start_with("From \n")
116
- end
117
- end
118
-
119
- context "when original message 'from' is not a well-formed address" do
120
- let(:message_body) { msg_bad_from }
121
-
122
- it "'from' is empty string" do
123
- expect(subject.to_serialized).to start_with("From \n")
124
- end
125
- end
126
-
127
- context "when original message 'from' is nil and " \
128
- "'envelope from' is nil and 'return path' is available" do
129
- let(:message_body) { msg_no_from_but_return_path }
130
-
131
- it "'return path' is used as 'from'" do
132
- expect(subject.to_serialized).to start_with("From #{from}\n")
133
- end
134
- end
135
-
136
- context "with no from and a 'Sender'" do
137
- let(:message_body) { msg_no_from_but_sender }
138
-
139
- it "Sender is used as 'from'" do
140
- expect(subject.to_serialized).to start_with("From #{from}\n")
141
- end
142
- end
143
- end
144
-
145
- describe "#date" do
146
- let(:message_body) { msg_good }
147
-
148
- it "returns the date" do
149
- expect(subject.date).to eq(date)
150
- end
151
-
152
- context "with incorrect minutes and seconds" do
153
- let(:message_body) { msg_bad_date }
154
-
155
- it "returns nil" do
156
- expect(subject.date).to be_nil
157
- end
158
- end
159
- end
160
-
161
- describe "#imap_body" do
162
- let(:message_body) { "Ciao" }
163
-
164
- it "returns the supplied body" do
165
- expect(subject.imap_body).to eq(message_body)
166
- end
167
-
168
- context "when newlines are not IMAP standard" do
169
- let(:message_body) { "Ciao\nHello" }
170
- let(:corrected) { "Ciao\r\nHello" }
171
-
172
- it "corrects them" do
173
- expect(subject.imap_body).to eq(corrected)
174
- end
175
- end
176
- end
177
- end
@@ -1,7 +0,0 @@
1
- describe Email::Provider::AppleMail do
2
- describe "#host" do
3
- it "returns host" do
4
- expect(subject.host).to eq("imap.mail.me.com")
5
- end
6
- end
7
- end
@@ -1,11 +0,0 @@
1
- describe Email::Provider::Base do
2
- describe "#options" do
3
- it "returns options" do
4
- expect(subject.options).to be_a(Hash)
5
- end
6
-
7
- it "forces TLSv1_2" do
8
- expect(subject.options[:ssl][:ssl_version]).to eq(:TLSv1_2)
9
- end
10
- end
11
- end
@@ -1,7 +0,0 @@
1
- describe Email::Provider::Fastmail do
2
- describe "#host" do
3
- it "returns host" do
4
- expect(subject.host).to eq("imap.fastmail.com")
5
- end
6
- end
7
- end
@@ -1,7 +0,0 @@
1
- describe Email::Provider::GMail do
2
- describe "#host" do
3
- it "returns host" do
4
- expect(subject.host).to eq("imap.gmail.com")
5
- end
6
- end
7
- end
@@ -1,27 +0,0 @@
1
- describe Email::Provider do
2
- describe ".for_address" do
3
- context "with known providers" do
4
- [
5
- ["fastmail.com", "Fastmail .com", Email::Provider::Fastmail],
6
- ["fastmail.fm", "Fastmail .fm", Email::Provider::Fastmail],
7
- ["gmail.com", "GMail", Email::Provider::GMail],
8
- ["icloud.com", "Apple Mail icloud.com", Email::Provider::AppleMail],
9
- ["mac.com", "Apple Mail mac.com", Email::Provider::AppleMail],
10
- ["me.com", "Apple Mail me.com", Email::Provider::AppleMail]
11
- ].each do |domain, name, klass|
12
- it "recognizes #{name} addresses" do
13
- address = "foo@#{domain}"
14
- expect(described_class.for_address(address)).to be_a(klass)
15
- end
16
- end
17
- end
18
-
19
- context "with unknown providers" do
20
- it "returns the Unknown provider" do
21
- result = described_class.for_address("foo@unknown.com")
22
-
23
- expect(result).to be_a(Email::Provider::Unknown)
24
- end
25
- end
26
- end
27
- end
@@ -1,405 +0,0 @@
1
- require "ostruct"
2
-
3
- describe Imap::Backup::Account::Connection do
4
- BACKUP_FOLDER = "backup_folder".freeze
5
- FOLDER_CONFIG = {name: BACKUP_FOLDER}.freeze
6
- FOLDER_NAME = "my_folder".freeze
7
- GMAIL_IMAP_SERVER = "imap.gmail.com".freeze
8
- IMAP_FOLDER = "imap_folder".freeze
9
- LOCAL_PATH = "local_path".freeze
10
- LOCAL_UID = "local_uid".freeze
11
- PASSWORD = "secret".freeze
12
- ROOT_NAME = "foo".freeze
13
- SERVER = "imap.example.com".freeze
14
- USERNAME = "username@example.com".freeze
15
-
16
- subject { described_class.new(account) }
17
-
18
- let(:client) do
19
- instance_double(
20
- Imap::Backup::Client::Default, authenticate: nil, login: nil, disconnect: nil
21
- )
22
- end
23
- let(:imap_folders) { [] }
24
- let(:account) do
25
- instance_double(
26
- Imap::Backup::Account,
27
- username: USERNAME,
28
- password: PASSWORD,
29
- local_path: LOCAL_PATH,
30
- folders: config_folders,
31
- server: server,
32
- connection_options: nil
33
- )
34
- end
35
- let(:config_folders) { [FOLDER_CONFIG] }
36
- let(:root_info) do
37
- instance_double(Net::IMAP::MailboxList, name: ROOT_NAME)
38
- end
39
- let(:serializer) do
40
- instance_double(
41
- Imap::Backup::Serializer::Mbox,
42
- folder: serialized_folder,
43
- force_uid_validity: nil,
44
- apply_uid_validity: new_uid_validity,
45
- uids: [LOCAL_UID]
46
- )
47
- end
48
- let(:serialized_folder) { nil }
49
- let(:server) { SERVER }
50
- let(:new_uid_validity) { nil }
51
-
52
- before do
53
- allow(Imap::Backup::Client::Default).to receive(:new) { client }
54
- allow(client).to receive(:list) { imap_folders }
55
- allow(Imap::Backup::Utils).to receive(:make_folder)
56
- end
57
-
58
- shared_examples "connects to IMAP" do
59
- it "logs in to the imap server" do
60
- expect(client).to have_received(:login)
61
- end
62
- end
63
-
64
- describe "#client" do
65
- let(:result) { subject.client }
66
-
67
- it "returns the IMAP connection" do
68
- expect(result).to eq(client)
69
- end
70
-
71
- it "uses the password" do
72
- result
73
-
74
- expect(client).to have_received(:login).with(USERNAME, PASSWORD)
75
- end
76
-
77
- context "when the first login attempt fails" do
78
- before do
79
- outcomes = [-> { raise EOFError }, -> { true }]
80
- allow(client).to receive(:login) { outcomes.shift.call }
81
- end
82
-
83
- it "retries" do
84
- subject.client
85
-
86
- expect(client).to have_received(:login).twice
87
- end
88
- end
89
-
90
- context "when run" do
91
- before { subject.client }
92
-
93
- include_examples "connects to IMAP"
94
- end
95
- end
96
-
97
- describe "#folder_names" do
98
- let(:imap_folders) do
99
- [IMAP_FOLDER]
100
- end
101
-
102
- it "returns the list of folders" do
103
- expect(subject.folder_names).to eq([IMAP_FOLDER])
104
- end
105
- end
106
-
107
- describe "#status" do
108
- let(:folder) do
109
- instance_double(
110
- Imap::Backup::Account::Folder,
111
- uids: [remote_uid],
112
- name: IMAP_FOLDER
113
- )
114
- end
115
- let(:remote_uid) { "remote_uid" }
116
-
117
- before do
118
- allow(Imap::Backup::Account::Folder).to receive(:new) { folder }
119
- allow(Imap::Backup::Serializer::Mbox).to receive(:new) { serializer }
120
- end
121
-
122
- it "creates the path" do
123
- expect(Imap::Backup::Utils).to receive(:make_folder)
124
-
125
- subject.status
126
- end
127
-
128
- it "returns the names of folders" do
129
- expect(subject.status[0][:name]).to eq(IMAP_FOLDER)
130
- end
131
-
132
- it "returns local message uids" do
133
- expect(subject.status[0][:local]).to eq([LOCAL_UID])
134
- end
135
-
136
- it "retrieves the available uids" do
137
- expect(subject.status[0][:remote]).to eq([remote_uid])
138
- end
139
- end
140
-
141
- describe "#run_backup" do
142
- let(:folder) do
143
- instance_double(
144
- Imap::Backup::Account::Folder,
145
- name: IMAP_FOLDER,
146
- exist?: exists,
147
- uid_validity: uid_validity
148
- )
149
- end
150
- let(:exists) { true }
151
- let(:uid_validity) { 123 }
152
- let(:downloader) { instance_double(Imap::Backup::Downloader, run: nil) }
153
-
154
- before do
155
- allow(Imap::Backup::Downloader).
156
- to receive(:new).with(folder, serializer, anything) { downloader }
157
- allow(Imap::Backup::Account::Folder).to receive(:new).
158
- with(subject, BACKUP_FOLDER) { folder }
159
- allow(Imap::Backup::Serializer::Mbox).to receive(:new).
160
- with(LOCAL_PATH, IMAP_FOLDER) { serializer }
161
- end
162
-
163
- context "with supplied config_folders" do
164
- it "runs the downloader" do
165
- expect(downloader).to receive(:run)
166
-
167
- subject.run_backup
168
- end
169
-
170
- context "when a folder does not exist" do
171
- let(:exists) { false }
172
-
173
- it "does not run the downloader" do
174
- expect(downloader).to_not receive(:run)
175
-
176
- subject.run_backup
177
- end
178
- end
179
- end
180
-
181
- context "without supplied config_folders" do
182
- let(:imap_folders) { [ROOT_NAME] }
183
-
184
- before do
185
- allow(Imap::Backup::Account::Folder).to receive(:new).
186
- with(subject, ROOT_NAME) { folder }
187
- allow(Imap::Backup::Serializer::Mbox).to receive(:new).
188
- with(LOCAL_PATH, ROOT_NAME) { serializer }
189
- end
190
-
191
- context "when supplied config_folders is nil" do
192
- let(:config_folders) { nil }
193
-
194
- it "runs the downloader for each folder" do
195
- expect(downloader).to receive(:run).exactly(:once)
196
-
197
- subject.run_backup
198
- end
199
- end
200
-
201
- context "when supplied config_folders is an empty list" do
202
- let(:config_folders) { [] }
203
-
204
- it "runs the downloader for each folder" do
205
- expect(downloader).to receive(:run).exactly(:once)
206
-
207
- subject.run_backup
208
- end
209
- end
210
-
211
- context "when the imap server doesn't return folders" do
212
- let(:config_folders) { nil }
213
- let(:imap_folders) { [] }
214
-
215
- it "fails" do
216
- expect do
217
- subject.run_backup
218
- end.to raise_error(RuntimeError, /Unable to get folder list/)
219
- end
220
- end
221
- end
222
-
223
- context "when the IMAP session expires" do
224
- before do
225
- data = OpenStruct.new(data: "Session expired")
226
- response = OpenStruct.new(data: data)
227
- outcomes = [
228
- -> { raise Net::IMAP::ByeResponseError, response },
229
- -> { nil }
230
- ]
231
- allow(downloader).to receive(:run) { outcomes.shift.call }
232
- end
233
-
234
- it "reconnects" do
235
- expect(downloader).to receive(:run).exactly(:twice)
236
-
237
- subject.run_backup
238
- end
239
- end
240
-
241
- context "when run" do
242
- before { subject.run_backup }
243
-
244
- include_examples "connects to IMAP"
245
- end
246
- end
247
-
248
- describe "#restore" do
249
- let(:folder) do
250
- instance_double(
251
- Imap::Backup::Account::Folder,
252
- create: nil,
253
- uids: uids,
254
- name: IMAP_FOLDER,
255
- uid_validity: uid_validity
256
- )
257
- end
258
- let(:uids) { [99] }
259
- let(:uid_validity) { 123 }
260
- let(:serialized_folder) { "old name" }
261
- let(:uploader) do
262
- instance_double(Imap::Backup::Uploader, run: false)
263
- end
264
- let(:updated_uploader) do
265
- instance_double(Imap::Backup::Uploader, run: false)
266
- end
267
- let(:updated_folder) do
268
- instance_double(
269
- Imap::Backup::Account::Folder,
270
- create: nil,
271
- uid_validity: "new uid validity"
272
- )
273
- end
274
- let(:updated_serializer) do
275
- instance_double(
276
- Imap::Backup::Serializer::Mbox, force_uid_validity: nil
277
- )
278
- end
279
-
280
- before do
281
- allow(Imap::Backup::Account::Folder).to receive(:new).
282
- with(subject, FOLDER_NAME) { folder }
283
- allow(Imap::Backup::Serializer::Mbox).to receive(:new).
284
- with(anything, FOLDER_NAME) { serializer }
285
- allow(Imap::Backup::Account::Folder).to receive(:new).
286
- with(subject, "new name") { updated_folder }
287
- allow(Imap::Backup::Serializer::Mbox).to receive(:new).
288
- with(anything, "new name") { updated_serializer }
289
- allow(Imap::Backup::Uploader).to receive(:new).
290
- with(folder, serializer) { uploader }
291
- allow(Imap::Backup::Uploader).to receive(:new).
292
- with(updated_folder, updated_serializer) { updated_uploader }
293
- allow(Pathname).to receive(:glob).
294
- and_yield(Pathname.new(File.join(LOCAL_PATH, "#{FOLDER_NAME}.imap")))
295
- end
296
-
297
- it "sets local uid validity" do
298
- expect(serializer).to receive(:apply_uid_validity).with(uid_validity)
299
-
300
- subject.restore
301
- end
302
-
303
- context "when folders exist with contents" do
304
- context "when the local folder is renamed" do
305
- let(:new_uid_validity) { "new name" }
306
-
307
- it "creates the new folder" do
308
- expect(updated_folder).to receive(:create)
309
-
310
- subject.restore
311
- end
312
-
313
- it "sets the renamed folder's uid validity" do
314
- expect(updated_serializer).
315
- to receive(:force_uid_validity).with("new uid validity")
316
-
317
- subject.restore
318
- end
319
-
320
- it "creates the uploader with updated folder and serializer" do
321
- expect(updated_uploader).to receive(:run)
322
-
323
- subject.restore
324
- end
325
- end
326
-
327
- context "when the local folder is not renamed" do
328
- it "runs the uploader" do
329
- expect(uploader).to receive(:run)
330
-
331
- subject.restore
332
- end
333
- end
334
- end
335
-
336
- context "when folders don't exist or are empty" do
337
- let(:uids) { [] }
338
-
339
- it "creates the folder" do
340
- expect(folder).to receive(:create)
341
-
342
- subject.restore
343
- end
344
-
345
- it "forces local uid validity" do
346
- expect(serializer).to receive(:force_uid_validity).with(uid_validity)
347
-
348
- subject.restore
349
- end
350
-
351
- it "runs the uploader" do
352
- expect(uploader).to receive(:run)
353
-
354
- subject.restore
355
- end
356
- end
357
- end
358
-
359
- describe "#reconnect" do
360
- context "when the IMAP connection has been used" do
361
- before { subject.client }
362
-
363
- it "disconnects from the server" do
364
- expect(client).to receive(:disconnect)
365
-
366
- subject.reconnect
367
- end
368
- end
369
-
370
- context "when the IMAP connection has not been used" do
371
- it "does not disconnect from the server" do
372
- expect(client).to_not receive(:disconnect)
373
-
374
- subject.reconnect
375
- end
376
- end
377
-
378
- it "causes reconnection on future access" do
379
- expect(Imap::Backup::Client::Default).to receive(:new)
380
-
381
- subject.reconnect
382
- subject.client
383
- end
384
- end
385
-
386
- describe "#disconnect" do
387
- context "when the IMAP connection has been used" do
388
- it "disconnects from the server" do
389
- subject.client
390
-
391
- expect(client).to receive(:disconnect)
392
-
393
- subject.disconnect
394
- end
395
- end
396
-
397
- context "when the IMAP connection has not been used" do
398
- it "does not disconnect from the server" do
399
- expect(client).to_not receive(:disconnect)
400
-
401
- subject.disconnect
402
- end
403
- end
404
- end
405
- end