imap-backup 2.0.0 → 2.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/.rspec +0 -1
  3. data/.rspec-all +2 -0
  4. data/.rubocop.yml +15 -2
  5. data/.rubocop_todo.yml +58 -0
  6. data/.travis.yml +15 -2
  7. data/README.md +14 -22
  8. data/Rakefile +6 -3
  9. data/bin/imap-backup +5 -11
  10. data/imap-backup.gemspec +10 -6
  11. data/lib/email/mboxrd/message.rb +16 -16
  12. data/lib/imap/backup/account/connection.rb +38 -22
  13. data/lib/imap/backup/account/folder.rb +23 -7
  14. data/lib/imap/backup/configuration/account.rb +25 -21
  15. data/lib/imap/backup/configuration/asker.rb +3 -2
  16. data/lib/imap/backup/configuration/connection_tester.rb +1 -1
  17. data/lib/imap/backup/configuration/folder_chooser.rb +32 -5
  18. data/lib/imap/backup/configuration/list.rb +2 -0
  19. data/lib/imap/backup/configuration/setup.rb +2 -1
  20. data/lib/imap/backup/configuration/store.rb +3 -6
  21. data/lib/imap/backup/downloader.rb +8 -7
  22. data/lib/imap/backup/serializer/mbox.rb +44 -25
  23. data/lib/imap/backup/serializer/mbox_enumerator.rb +31 -0
  24. data/lib/imap/backup/serializer/mbox_store.rb +35 -32
  25. data/lib/imap/backup/uploader.rb +11 -2
  26. data/lib/imap/backup/utils.rb +11 -9
  27. data/lib/imap/backup/version.rb +2 -2
  28. data/spec/features/backup_spec.rb +6 -5
  29. data/spec/features/helper.rb +1 -1
  30. data/spec/features/restore_spec.rb +75 -27
  31. data/spec/features/support/backup_directory.rb +7 -7
  32. data/spec/features/support/email_server.rb +15 -11
  33. data/spec/features/support/shared/connection_context.rb +2 -2
  34. data/spec/features/support/shared/message_fixtures.rb +8 -0
  35. data/spec/spec_helper.rb +1 -1
  36. data/spec/support/fixtures.rb +2 -2
  37. data/spec/support/higline_test_helpers.rb +1 -1
  38. data/spec/unit/email/mboxrd/message_spec.rb +73 -53
  39. data/spec/unit/email/provider_spec.rb +3 -5
  40. data/spec/unit/imap/backup/account/connection_spec.rb +82 -59
  41. data/spec/unit/imap/backup/account/folder_spec.rb +75 -37
  42. data/spec/unit/imap/backup/configuration/account_spec.rb +95 -61
  43. data/spec/unit/imap/backup/configuration/asker_spec.rb +43 -45
  44. data/spec/unit/imap/backup/configuration/connection_tester_spec.rb +21 -22
  45. data/spec/unit/imap/backup/configuration/folder_chooser_spec.rb +66 -33
  46. data/spec/unit/imap/backup/configuration/list_spec.rb +32 -11
  47. data/spec/unit/imap/backup/configuration/setup_spec.rb +97 -56
  48. data/spec/unit/imap/backup/configuration/store_spec.rb +30 -25
  49. data/spec/unit/imap/backup/downloader_spec.rb +28 -26
  50. data/spec/unit/imap/backup/serializer/mbox_enumerator_spec.rb +45 -0
  51. data/spec/unit/imap/backup/serializer/mbox_spec.rb +109 -51
  52. data/spec/unit/imap/backup/serializer/mbox_store_spec.rb +232 -20
  53. data/spec/unit/imap/backup/uploader_spec.rb +23 -9
  54. data/spec/unit/imap/backup/utils_spec.rb +14 -15
  55. data/spec/unit/imap/backup_spec.rb +28 -0
  56. metadata +13 -7
@@ -0,0 +1,45 @@
1
+ require "imap/backup/serializer/mbox_enumerator"
2
+
3
+ describe Imap::Backup::Serializer::MboxEnumerator do
4
+ subject { described_class.new(mbox_pathname) }
5
+
6
+ let(:mbox_pathname) { "/mbox/pathname" }
7
+ let(:mbox_file) { instance_double(File) }
8
+ let(:lines) { message1 + message2 + [nil] }
9
+ let(:message1) do
10
+ [
11
+ "From Frida\r\n",
12
+ "Hello\r\n"
13
+ ]
14
+ end
15
+ let(:message2) do
16
+ [
17
+ "From John\r\n",
18
+ "Hi\r\n"
19
+ ]
20
+ end
21
+
22
+ before do
23
+ allow(File).to receive(:open).and_call_original
24
+ allow(File).to receive(:open).with(mbox_pathname, "rb").and_yield(mbox_file)
25
+ allow(mbox_file).to receive(:gets).and_return(*lines)
26
+ end
27
+
28
+ describe "#each" do
29
+ it "reads files as binary" do
30
+ expect(File).to receive(:open).with(mbox_pathname, "rb")
31
+ subject.each {}
32
+ end
33
+
34
+ it "yields messages" do
35
+ expect { |b| subject.each(&b) }.
36
+ to yield_successive_args(message1.join, message2.join)
37
+ end
38
+
39
+ context "without a block" do
40
+ it "returns an Enumerator" do
41
+ expect(subject.each).to be_a(Enumerator)
42
+ end
43
+ end
44
+ end
45
+ end
@@ -1,4 +1,6 @@
1
1
  describe Imap::Backup::Serializer::Mbox do
2
+ subject { described_class.new(base_path, imap_folder) }
3
+
2
4
  let(:base_path) { "/base/path" }
3
5
  let(:store) do
4
6
  instance_double(
@@ -7,7 +9,8 @@ describe Imap::Backup::Serializer::Mbox do
7
9
  rename: nil,
8
10
  uids: nil,
9
11
  uid_validity: existing_uid_validity,
10
- "uid_validity=": nil
12
+ "uid_validity=": nil,
13
+ update_uid: nil
11
14
  )
12
15
  end
13
16
  let(:imap_folder) { "folder" }
@@ -20,103 +23,91 @@ describe Imap::Backup::Serializer::Mbox do
20
23
  allow(Imap::Backup::Utils).to receive(:mode) { permissions }
21
24
  allow(Imap::Backup::Utils).to receive(:check_permissions) { true }
22
25
  allow(File).to receive(:directory?) { dir_exists }
23
- end
24
-
25
- subject { described_class.new(base_path, imap_folder) }
26
-
27
- before do
28
26
  allow(FileUtils).to receive(:chmod)
29
27
  allow(Imap::Backup::Serializer::MboxStore).to receive(:new) { store }
30
28
  end
31
29
 
32
- context "containing directory" do
33
- before { subject.uids }
34
-
35
- context "when the IMAP folder has multiple elements" do
30
+ describe "folder path" do
31
+ context "when it has multiple elements" do
36
32
  let(:imap_folder) { "folder/path" }
37
33
 
38
34
  context "when the containing directory is missing" do
39
35
  let(:dir_exists) { false }
40
36
 
41
37
  it "is created" do
42
- expect(Imap::Backup::Utils).to have_received(:make_folder).
38
+ expect(Imap::Backup::Utils).to receive(:make_folder).
43
39
  with(base_path, File.dirname(imap_folder), 0o700)
40
+
41
+ subject.uids
44
42
  end
45
43
  end
46
44
  end
47
45
 
48
- context "when the containing directory permissons are incorrect" do
46
+ context "when permissions are incorrect" do
49
47
  let(:permissions) { 0o777 }
50
48
 
51
49
  it "corrects them" do
52
50
  path = File.expand_path(File.join(base_path, File.dirname(imap_folder)))
53
- expect(FileUtils).to have_received(:chmod).with(0o700, path)
51
+ expect(FileUtils).to receive(:chmod).with(0o700, path)
52
+
53
+ subject.uids
54
54
  end
55
55
  end
56
56
 
57
- context "when the containing directory permissons are correct" do
57
+ context "when permissons are correct" do
58
58
  it "does nothing" do
59
- expect(FileUtils).to_not have_received(:chmod)
59
+ expect(FileUtils).to_not receive(:chmod)
60
+
61
+ subject.uids
60
62
  end
61
63
  end
62
64
 
63
- context "when the containing directory exists" do
65
+ context "when it exists" do
64
66
  it "is not created" do
65
- expect(Imap::Backup::Utils).to_not have_received(:make_folder).
67
+ expect(Imap::Backup::Utils).to_not receive(:make_folder).
66
68
  with(base_path, File.dirname(imap_folder), 0o700)
67
- end
68
- end
69
- end
70
-
71
- context "#uids" do
72
- it "calls the store" do
73
- subject.uids
74
-
75
- expect(store).to have_received(:uids)
76
- end
77
- end
78
-
79
- context "#save" do
80
- it "calls the store" do
81
- subject.save("foo", "bar")
82
69
 
83
- expect(store).to have_received(:add)
70
+ subject.uids
71
+ end
84
72
  end
85
73
  end
86
74
 
87
- context "#set_uid_validity" do
88
- let(:result) { subject.set_uid_validity("aaa") }
89
-
75
+ describe "#apply_uid_validity" do
90
76
  context "when the existing uid validity is unset" do
91
- let!(:result) { super() }
92
-
93
77
  it "sets uid validity" do
94
- expect(store).to have_received(:uid_validity=).with("aaa")
78
+ expect(store).to receive(:uid_validity=).with("aaa")
79
+
80
+ subject.apply_uid_validity("aaa")
95
81
  end
96
82
 
97
83
  it "does not rename the store" do
98
- expect(store).to_not have_received(:rename)
84
+ expect(store).to_not receive(:rename)
85
+
86
+ subject.apply_uid_validity("aaa")
99
87
  end
100
88
 
101
89
  it "returns nil" do
102
- expect(result).to be_nil
90
+ expect(subject.apply_uid_validity("aaa")).to be_nil
103
91
  end
104
92
  end
105
93
 
106
94
  context "when the uid validity is unchanged" do
107
- let!(:result) { super() }
108
95
  let(:existing_uid_validity) { "aaa" }
109
96
 
110
97
  it "does not set uid validity" do
111
- expect(store).to_not have_received(:uid_validity=)
98
+ expect(store).to_not receive(:uid_validity=)
99
+
100
+ subject.apply_uid_validity("aaa")
112
101
  end
113
102
 
114
103
  it "does not rename the store" do
115
- expect(store).to_not have_received(:rename)
104
+ expect(store).to_not receive(:rename)
105
+
106
+ subject.apply_uid_validity("aaa")
116
107
  end
117
108
 
118
109
  it "returns nil" do
119
- expect(result).to be_nil
110
+ expect(subject.apply_uid_validity("aaa")).to be_nil
120
111
  end
121
112
  end
122
113
 
@@ -131,20 +122,23 @@ describe Imap::Backup::Serializer::Mbox do
131
122
  allow(Imap::Backup::Serializer::MboxStore).
132
123
  to receive(:new).with(anything, /bbb/) { existing_store }
133
124
  allow(existing_store).to receive(:exist?).and_return(exists, false)
134
- result
135
125
  end
136
126
 
137
127
  it "sets uid validity" do
138
- expect(store).to have_received(:uid_validity=).with("aaa")
128
+ expect(store).to receive(:uid_validity=).with("aaa")
129
+
130
+ subject.apply_uid_validity("aaa")
139
131
  end
140
132
 
141
133
  context "when adding the uid validity does not cause a name clash" do
142
134
  it "renames the store, adding the existing uid validity" do
143
- expect(store).to have_received(:rename).with("folder.bbb")
135
+ expect(store).to receive(:rename).with("folder.bbb")
136
+
137
+ subject.apply_uid_validity("aaa")
144
138
  end
145
139
 
146
140
  it "returns the new name" do
147
- expect(result).to eq("folder.bbb")
141
+ expect(subject.apply_uid_validity("aaa")).to eq("folder.bbb")
148
142
  end
149
143
  end
150
144
 
@@ -152,13 +146,77 @@ describe Imap::Backup::Serializer::Mbox do
152
146
  let(:exists) { true }
153
147
 
154
148
  it "renames the store, adding the existing uid validity and a digit" do
155
- expect(store).to have_received(:rename).with("folder.bbb.1")
149
+ expect(store).to receive(:rename).with("folder.bbb.1")
150
+
151
+ subject.apply_uid_validity("aaa")
156
152
  end
157
153
 
158
154
  it "returns the new name" do
159
- expect(result).to eq("folder.bbb.1")
155
+ expect(subject.apply_uid_validity("aaa")).to eq("folder.bbb.1")
160
156
  end
161
157
  end
162
158
  end
163
159
  end
160
+
161
+ describe "#force_uid_validity" do
162
+ it "sets the uid_validity" do
163
+ expect(store).to receive(:uid_validity=).with("66")
164
+
165
+ subject.force_uid_validity("66")
166
+ end
167
+ end
168
+
169
+ describe "#uids" do
170
+ it "calls the store" do
171
+ expect(store).to receive(:uids)
172
+
173
+ subject.uids
174
+ end
175
+ end
176
+
177
+ describe "#load" do
178
+ before { allow(store).to receive(:load).with("66") { "xxx" } }
179
+
180
+ it "returns the value loaded by the store" do
181
+ expect(subject.load("66")).to eq("xxx")
182
+ end
183
+ end
184
+
185
+ describe "#each_message" do
186
+ it "calls the store" do
187
+ expect(store).to receive(:each_message).with([1])
188
+
189
+ subject.each_message([1])
190
+ end
191
+ end
192
+
193
+ describe "#save" do
194
+ it "calls the store" do
195
+ expect(store).to receive(:add).with("foo", "bar")
196
+
197
+ subject.save("foo", "bar")
198
+ end
199
+ end
200
+
201
+ describe "#rename" do
202
+ it "calls the store" do
203
+ expect(store).to receive(:rename).with("foo")
204
+
205
+ subject.rename("foo")
206
+ end
207
+
208
+ it "updates the folder name" do
209
+ subject.rename("foo")
210
+
211
+ expect(subject.folder).to eq("foo")
212
+ end
213
+ end
214
+
215
+ describe "#update_uid" do
216
+ it "calls the store" do
217
+ expect(store).to receive(:update_uid).with("foo", "bar")
218
+
219
+ subject.update_uid("foo", "bar")
220
+ end
221
+ end
164
222
  end
@@ -1,23 +1,24 @@
1
1
  describe Imap::Backup::Serializer::MboxStore do
2
+ subject { described_class.new(base_path, folder) }
3
+
2
4
  let(:base_path) { "/base/path" }
3
5
  let(:folder) { "the/folder" }
4
6
  let(:folder_path) { File.join(base_path, folder) }
5
- let(:imap_pathname) { folder_path + ".imap" }
7
+ let(:imap_pathname) { "#{folder_path}.imap" }
6
8
  let(:imap_exists) { true }
7
- let(:imap_file) { double("File - imap", write: nil, close: nil) }
8
- let(:mbox_pathname) { folder_path + ".mbox" }
9
+ let(:imap_file) { instance_double(File, write: nil, close: nil) }
10
+ let(:mbox_pathname) { "#{folder_path}.mbox" }
9
11
  let(:mbox_exists) { true }
10
- let(:mbox_file) { double("File - mbox", write: nil, close: nil) }
12
+ let(:mbox_file) { instance_double(File, write: nil, close: nil) }
11
13
  let(:uids) { [3, 2, 1] }
12
14
  let(:imap_content) do
13
15
  {
14
16
  version: Imap::Backup::Serializer::MboxStore::CURRENT_VERSION,
15
- uid_validity: 123,
16
- uids: uids.sort
17
+ uid_validity: uid_validity,
18
+ uids: uids
17
19
  }.to_json
18
20
  end
19
-
20
- subject { described_class.new(base_path, folder) }
21
+ let(:uid_validity) { 123 }
21
22
 
22
23
  before do
23
24
  allow(File).to receive(:exist?).and_call_original
@@ -40,9 +41,32 @@ describe Imap::Backup::Serializer::MboxStore do
40
41
  allow(FileUtils).to receive(:chmod)
41
42
  end
42
43
 
43
- context "#uids" do
44
- it "returns the backed-up uids as sorted integers" do
45
- expect(subject.uids).to eq(uids.map(&:to_i).sort)
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))
46
70
  end
47
71
 
48
72
  context "when the imap file does not exist" do
@@ -53,6 +77,34 @@ describe Imap::Backup::Serializer::MboxStore do
53
77
  end
54
78
  end
55
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
+
56
108
  context "when the mbox does not exist" do
57
109
  let(:mbox_exists) { false }
58
110
 
@@ -62,7 +114,7 @@ describe Imap::Backup::Serializer::MboxStore do
62
114
  end
63
115
  end
64
116
 
65
- context "#add" do
117
+ describe "#add" do
66
118
  let(:mbox_formatted_message) { "message in mbox format" }
67
119
  let(:message_uid) { "999" }
68
120
  let(:message) do
@@ -74,27 +126,36 @@ describe Imap::Backup::Serializer::MboxStore do
74
126
  let(:updated_imap_content) do
75
127
  {
76
128
  version: Imap::Backup::Serializer::MboxStore::CURRENT_VERSION,
77
- uid_validity: 123,
78
- uids: (uids + [999]).sort
129
+ uid_validity: uid_validity,
130
+ uids: uids + [999]
79
131
  }.to_json
80
132
  end
81
133
 
82
134
  before do
83
- allow(Email::Mboxrd::Message).to receive(:new).and_return(message)
135
+ allow(Email::Mboxrd::Message).to receive(:new) { message }
84
136
  allow(File).to receive(:open).with(mbox_pathname, "ab") { mbox_file }
85
- subject.uid_validity = 123
86
137
  end
87
138
 
88
139
  it "saves the message to the mbox" do
89
- subject.add(message_uid, "The\nemail\n")
140
+ expect(mbox_file).to receive(:write).with(mbox_formatted_message)
90
141
 
91
- expect(mbox_file).to have_received(:write).with(mbox_formatted_message)
142
+ subject.add(message_uid, "The\nemail\n")
92
143
  end
93
144
 
94
145
  it "saves the uid to the imap file" do
146
+ expect(imap_file).to receive(:write).with(updated_imap_content)
147
+
95
148
  subject.add(message_uid, "The\nemail\n")
149
+ end
150
+
151
+ context "when the message is already downloaded" do
152
+ let(:uids) { [999] }
96
153
 
97
- expect(imap_file).to have_received(:write).with(updated_imap_content)
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
98
159
  end
99
160
 
100
161
  context "when the message causes parsing errors" do
@@ -103,8 +164,9 @@ describe Imap::Backup::Serializer::MboxStore do
103
164
  end
104
165
 
105
166
  it "skips the message" do
167
+ expect(mbox_file).to_not receive(:write)
168
+
106
169
  subject.add(message_uid, "The\nemail\n")
107
- expect(mbox_file).to_not have_received(:write)
108
170
  end
109
171
 
110
172
  it "does not fail" do
@@ -114,4 +176,154 @@ describe Imap::Backup::Serializer::MboxStore do
114
176
  end
115
177
  end
116
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
117
329
  end