imap-backup 2.0.0 → 2.2.2

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