imap-backup 2.1.1 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (30) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +2 -0
  3. data/README.md +6 -2
  4. data/bin/imap-backup +1 -1
  5. data/lib/email/mboxrd/message.rb +0 -1
  6. data/lib/imap/backup/account/connection.rb +28 -21
  7. data/lib/imap/backup/account/folder.rb +0 -1
  8. data/lib/imap/backup/serializer/mbox_enumerator.rb +1 -1
  9. data/lib/imap/backup/uploader.rb +10 -1
  10. data/lib/imap/backup/version.rb +2 -2
  11. data/spec/features/restore_spec.rb +75 -27
  12. data/spec/features/support/email_server.rb +1 -3
  13. data/spec/features/support/shared/message_fixtures.rb +8 -0
  14. data/spec/unit/email/mboxrd/message_spec.rb +0 -6
  15. data/spec/unit/imap/backup/account/connection_spec.rb +58 -43
  16. data/spec/unit/imap/backup/account/folder_spec.rb +16 -20
  17. data/spec/unit/imap/backup/configuration/account_spec.rb +31 -25
  18. data/spec/unit/imap/backup/configuration/asker_spec.rb +20 -17
  19. data/spec/unit/imap/backup/configuration/connection_tester_spec.rb +6 -10
  20. data/spec/unit/imap/backup/configuration/folder_chooser_spec.rb +16 -10
  21. data/spec/unit/imap/backup/configuration/list_spec.rb +6 -3
  22. data/spec/unit/imap/backup/configuration/setup_spec.rb +40 -25
  23. data/spec/unit/imap/backup/configuration/store_spec.rb +18 -16
  24. data/spec/unit/imap/backup/downloader_spec.rb +14 -14
  25. data/spec/unit/imap/backup/serializer/mbox_enumerator_spec.rb +6 -1
  26. data/spec/unit/imap/backup/serializer/mbox_spec.rb +54 -40
  27. data/spec/unit/imap/backup/serializer/mbox_store_spec.rb +49 -31
  28. data/spec/unit/imap/backup/uploader_spec.rb +20 -7
  29. data/spec/unit/imap/backup/utils_spec.rb +8 -9
  30. metadata +2 -2
@@ -28,7 +28,7 @@ describe Imap::Backup::Account::Folder do
28
28
  describe "#uids" do
29
29
  let(:uids) { [5678, 123] }
30
30
 
31
- before { allow(imap).to receive(:uid_search).and_return(uids) }
31
+ before { allow(imap).to receive(:uid_search) { uids } }
32
32
 
33
33
  it "lists available messages" do
34
34
  expect(subject.uids).to eq(uids.reverse)
@@ -83,12 +83,6 @@ describe Imap::Backup::Account::Folder do
83
83
  expect(subject.fetch(123)).to be_nil
84
84
  end
85
85
  end
86
-
87
- it "sets the encoding on the message" do
88
- subject.fetch(123)
89
-
90
- expect(message_body).to have_received(:force_encoding).with("utf-8")
91
- end
92
86
  end
93
87
 
94
88
  describe "#folder" do
@@ -117,21 +111,22 @@ describe Imap::Backup::Account::Folder do
117
111
 
118
112
  describe "#create" do
119
113
  context "when the folder exists" do
120
- before { subject.create }
121
-
122
114
  it "is does not create the folder" do
123
- expect(imap).to_not have_received(:create)
115
+ expect(imap).to_not receive(:create)
116
+
117
+ subject.create
124
118
  end
125
119
  end
126
120
 
127
121
  context "when the folder doesn't exist" do
128
122
  before do
129
123
  allow(imap).to receive(:examine).and_raise(missing_mailbox_error)
130
- subject.create
131
124
  end
132
125
 
133
126
  it "is does not create the folder" do
134
- expect(imap).to have_received(:create)
127
+ expect(imap).to receive(:create)
128
+
129
+ subject.create
135
130
  end
136
131
  end
137
132
  end
@@ -168,26 +163,27 @@ describe Imap::Backup::Account::Folder do
168
163
  let(:append_response) do
169
164
  OpenStruct.new(data: OpenStruct.new(code: OpenStruct.new(data: "1 2")))
170
165
  end
171
- let(:result) { subject.append(message) }
172
-
173
- before do
174
- result
175
- end
176
166
 
177
167
  it "appends the message" do
178
- expect(imap).to have_received(:append)
168
+ expect(imap).to receive(:append)
169
+
170
+ subject.append(message)
179
171
  end
180
172
 
181
173
  it "sets the date and time" do
182
- expect(imap).to have_received(:append).
174
+ expect(imap).to receive(:append).
183
175
  with(anything, anything, anything, message_date)
176
+
177
+ subject.append(message)
184
178
  end
185
179
 
186
180
  it "returns the new uid" do
187
- expect(result).to eq(2)
181
+ expect(subject.append(message)).to eq(2)
188
182
  end
189
183
 
190
184
  it "set the new uid validity" do
185
+ subject.append(message)
186
+
191
187
  expect(subject.uid_validity).to eq(1)
192
188
  end
193
189
  end
@@ -1,23 +1,6 @@
1
1
  # rubocop:disable RSpec/NestedGroups
2
2
 
3
3
  describe Imap::Backup::Configuration::Account do
4
- class MockHighlineMenu
5
- attr_reader :choices
6
- attr_accessor :header
7
-
8
- def initialize
9
- @choices = {}
10
- end
11
-
12
- def choice(name, &block)
13
- choices[name] = block
14
- end
15
-
16
- def hidden(name, &block)
17
- choices[name] = block
18
- end
19
- end
20
-
21
4
  describe "#initialize" do
22
5
  subject { described_class.new(store, account, highline) }
23
6
 
@@ -35,8 +18,27 @@ describe Imap::Backup::Configuration::Account do
35
18
  describe "#run" do
36
19
  subject { described_class.new(store, account, highline) }
37
20
 
21
+ let(:highline_menu_class) do
22
+ Class.new do
23
+ attr_reader :choices
24
+ attr_accessor :header
25
+
26
+ def initialize
27
+ @choices = {}
28
+ end
29
+
30
+ def choice(name, &block)
31
+ choices[name] = block
32
+ end
33
+
34
+ def hidden(name, &block)
35
+ choices[name] = block
36
+ end
37
+ end
38
+ end
39
+
38
40
  let(:highline) { instance_double(HighLine) }
39
- let(:menu) { MockHighlineMenu.new }
41
+ let(:menu) { highline_menu_class.new }
40
42
  let(:store) do
41
43
  instance_double(Imap::Backup::Configuration::Store, accounts: accounts)
42
44
  end
@@ -73,15 +75,17 @@ describe Imap::Backup::Configuration::Account do
73
75
  end
74
76
 
75
77
  describe "preparation" do
76
- before { subject.run }
77
-
78
78
  it "clears the screen" do
79
- expect(Kernel).to have_received(:system).with("clear")
79
+ expect(Kernel).to receive(:system).with("clear")
80
+
81
+ subject.run
80
82
  end
81
83
 
82
84
  describe "menu" do
83
85
  it "shows the menu" do
84
- expect(highline).to have_received(:choose)
86
+ expect(highline).to receive(:choose)
87
+
88
+ subject.run
85
89
  end
86
90
  end
87
91
  end
@@ -240,8 +244,10 @@ describe Imap::Backup::Configuration::Account do
240
244
  let(:server) { "server" }
241
245
 
242
246
  before do
243
- allow(highline).to receive(:ask).with("server: ").and_return(server)
247
+ allow(highline).to receive(:ask).with("server: ") { server }
248
+
244
249
  subject.run
250
+
245
251
  menu.choices["modify server"].call
246
252
  end
247
253
 
@@ -310,7 +316,7 @@ describe Imap::Backup::Configuration::Account do
310
316
  describe "connection test" do
311
317
  before do
312
318
  allow(Imap::Backup::Configuration::ConnectionTester).
313
- to receive(:test).and_return("All fine")
319
+ to receive(:test) { "All fine" }
314
320
  allow(highline).to receive(:ask)
315
321
  subject.run
316
322
  menu.choices["test connection"].call
@@ -326,7 +332,7 @@ describe Imap::Backup::Configuration::Account do
326
332
  let(:confirmed) { true }
327
333
 
328
334
  before do
329
- allow(highline).to receive(:agree).and_return(confirmed)
335
+ allow(highline).to receive(:agree) { confirmed }
330
336
  subject.run
331
337
  catch :done do
332
338
  menu.choices["delete"].call
@@ -30,9 +30,9 @@ module Imap::Backup
30
30
  ].each do |method, params, prompt|
31
31
  context ".#{method}" do
32
32
  it "asks for input" do
33
- described_class.send(method, *params)
33
+ expect(highline).to receive(:ask).with("#{prompt}: ")
34
34
 
35
- expect(highline).to have_received(:ask).with("#{prompt}: ")
35
+ described_class.send(method, *params)
36
36
  end
37
37
 
38
38
  it "returns the answer" do
@@ -56,16 +56,15 @@ module Imap::Backup
56
56
  describe "#email" do
57
57
  let(:email) { "email@example.com" }
58
58
  let(:answer) { email }
59
- let(:result) { subject.email }
60
-
61
- before { result }
62
59
 
63
60
  it "asks for an email" do
64
- expect(highline).to have_received(:ask).with(/email/)
61
+ expect(highline).to receive(:ask).with(/email/)
62
+
63
+ subject.email
65
64
  end
66
65
 
67
66
  it "returns the address" do
68
- expect(result).to eq(email)
67
+ expect(subject.email).to eq(email)
69
68
  end
70
69
  end
71
70
 
@@ -73,7 +72,6 @@ module Imap::Backup
73
72
  let(:password1) { "password" }
74
73
  let(:password2) { "password" }
75
74
  let(:answers) { [true, false] }
76
- let(:result) { subject.password }
77
75
 
78
76
  before do
79
77
  i = 0
@@ -84,27 +82,32 @@ module Imap::Backup
84
82
  i += 1
85
83
  answer
86
84
  end
87
- result
88
85
  end
89
86
 
90
87
  it "asks for a password" do
91
- expect(highline).to have_received(:ask).with("password: ")
88
+ expect(highline).to receive(:ask).with("password: ")
89
+
90
+ subject.password
92
91
  end
93
92
 
94
93
  it "asks for confirmation" do
95
- expect(highline).to have_received(:ask).with("repeat password: ")
94
+ expect(highline).to receive(:ask).with("repeat password: ")
95
+
96
+ subject.password
96
97
  end
97
98
 
98
99
  it "returns the password" do
99
- expect(result).to eq(password1)
100
+ expect(subject.password).to eq(password1)
100
101
  end
101
102
 
102
103
  context "with different answers" do
103
104
  let(:password2) { "secret" }
104
105
 
105
106
  it "asks to continue" do
106
- expect(highline).to have_received(:agree).
107
+ expect(highline).to receive(:agree).
107
108
  at_least(:once).with(/Continue\?/)
109
+
110
+ subject.password
108
111
  end
109
112
  end
110
113
  end
@@ -112,22 +115,22 @@ module Imap::Backup
112
115
  describe "#backup_path" do
113
116
  let(:path) { "/path" }
114
117
  let(:answer) { path }
115
- let(:result) { subject.backup_path("", //) }
116
118
 
117
119
  before do
118
120
  allow(highline).to receive(:ask) do |&b|
119
121
  b.call query
120
122
  path
121
123
  end
122
- result
123
124
  end
124
125
 
125
126
  it "asks for a directory" do
126
- expect(highline).to have_received(:ask).with(/directory/)
127
+ expect(highline).to receive(:ask).with(/directory/)
128
+
129
+ subject.backup_path("", //)
127
130
  end
128
131
 
129
132
  it "returns the path" do
130
- expect(result).to eq(path)
133
+ expect(subject.backup_path("", //)).to eq(path)
131
134
  end
132
135
  end
133
136
  end
@@ -3,32 +3,28 @@ describe Imap::Backup::Configuration::ConnectionTester do
3
3
  let(:connection) do
4
4
  instance_double(Imap::Backup::Account::Connection, imap: nil)
5
5
  end
6
- let(:result) { subject.test("foo") }
7
6
 
8
7
  before do
9
8
  allow(Imap::Backup::Account::Connection).to receive(:new) { connection }
10
9
  end
11
10
 
12
11
  describe "call" do
13
- before { result }
14
-
15
12
  it "tries to connect" do
16
- expect(connection).to have_received(:imap)
13
+ expect(connection).to receive(:imap)
14
+
15
+ subject.test("foo")
17
16
  end
18
17
  end
19
18
 
20
19
  describe "success" do
21
- before { result }
22
-
23
20
  it "returns success" do
24
- expect(result).to match(/successful/)
21
+ expect(subject.test("foo")).to match(/successful/)
25
22
  end
26
23
  end
27
24
 
28
25
  describe "failure" do
29
26
  before do
30
27
  allow(connection).to receive(:imap).and_raise(error)
31
- result
32
28
  end
33
29
 
34
30
  context "with no connection" do
@@ -39,7 +35,7 @@ describe Imap::Backup::Configuration::ConnectionTester do
39
35
  end
40
36
 
41
37
  it "returns error" do
42
- expect(result).to match(/no response/i)
38
+ expect(subject.test("foo")).to match(/no response/i)
43
39
  end
44
40
  end
45
41
 
@@ -47,7 +43,7 @@ describe Imap::Backup::Configuration::ConnectionTester do
47
43
  let(:error) { "Error" }
48
44
 
49
45
  it "returns error" do
50
- expect(result).to match(/unexpected error/i)
46
+ expect(subject.test("foo")).to match(/unexpected error/i)
51
47
  end
52
48
  end
53
49
  end
@@ -22,13 +22,15 @@ describe Imap::Backup::Configuration::FolderChooser do
22
22
  end
23
23
 
24
24
  describe "display" do
25
- before { subject.run }
26
-
27
25
  it "clears the screen" do
28
- expect(Kernel).to have_received(:system).with("clear")
26
+ expect(Kernel).to receive(:system).with("clear")
27
+
28
+ subject.run
29
29
  end
30
30
 
31
31
  it "shows the menu" do
32
+ subject.run
33
+
32
34
  expect(output.string).to match %r{Add/remove folders}
33
35
  end
34
36
  end
@@ -114,13 +116,14 @@ describe Imap::Backup::Configuration::FolderChooser do
114
116
 
115
117
  before do
116
118
  allow(Imap::Backup::Configuration::Setup.highline).
117
- to receive(:ask).and_return("q")
118
- subject.run
119
+ to receive(:ask) { "q" }
119
120
  end
120
121
 
121
122
  it "asks to press a key" do
122
123
  expect(Imap::Backup::Configuration::Setup.highline).
123
- to have_received(:ask).with("Press a key ")
124
+ to receive(:ask).with("Press a key ")
125
+
126
+ subject.run
124
127
  end
125
128
  end
126
129
 
@@ -129,18 +132,21 @@ describe Imap::Backup::Configuration::FolderChooser do
129
132
  allow(Imap::Backup::Account::Connection).
130
133
  to receive(:new).with(account).and_raise("error")
131
134
  allow(Imap::Backup::Configuration::Setup.highline).
132
- to receive(:ask).and_return("q")
133
- subject.run
135
+ to receive(:ask) { "q" }
134
136
  end
135
137
 
136
138
  it "prints an error message" do
137
139
  expect(Imap::Backup.logger).
138
- to have_received(:warn).with("Connection failed")
140
+ to receive(:warn).with("Connection failed")
141
+
142
+ subject.run
139
143
  end
140
144
 
141
145
  it "asks to continue" do
142
146
  expect(Imap::Backup::Configuration::Setup.highline).
143
- to have_received(:ask).with("Press a key ")
147
+ to receive(:ask).with("Press a key ")
148
+
149
+ subject.run
144
150
  end
145
151
  end
146
152
  end
@@ -35,18 +35,21 @@ describe Imap::Backup::Configuration::List do
35
35
  allow(Imap::Backup::Configuration::Store).
36
36
  to receive(:exist?) { config_exists }
37
37
  allow(Imap::Backup).to receive(:setup_logging)
38
- subject.setup_logging
39
38
  end
40
39
 
41
40
  it "sets global logging level" do
42
- expect(Imap::Backup).to have_received(:setup_logging).with(store)
41
+ expect(Imap::Backup).to receive(:setup_logging).with(store)
42
+
43
+ subject.setup_logging
43
44
  end
44
45
 
45
46
  context "without a config" do
46
47
  let(:config_exists) { false }
47
48
 
48
49
  it "does nothing" do
49
- expect(Imap::Backup).to_not have_received(:setup_logging).with(store)
50
+ expect(Imap::Backup).to_not receive(:setup_logging).with(store)
51
+
52
+ subject.setup_logging
50
53
  end
51
54
  end
52
55
  end
@@ -52,15 +52,15 @@ describe Imap::Backup::Configuration::Setup do
52
52
  end
53
53
 
54
54
  it "clears the screen" do
55
- subject.run
55
+ expect(Kernel).to receive(:system).with("clear")
56
56
 
57
- expect(Kernel).to have_received(:system).with("clear")
57
+ subject.run
58
58
  end
59
59
 
60
60
  it "updates logging status" do
61
- subject.run
61
+ expect(Imap::Backup).to receive(:setup_logging)
62
62
 
63
- expect(Imap::Backup).to have_received(:setup_logging)
63
+ subject.run
64
64
  end
65
65
 
66
66
  describe "listing" do
@@ -97,15 +97,15 @@ describe Imap::Backup::Configuration::Setup do
97
97
  before do
98
98
  allow(input).to receive(:gets).and_return("1\n", "exit\n")
99
99
  allow(Imap::Backup::Configuration::Asker).to receive(:email).
100
- with(no_args).and_return("new@example.com")
100
+ with(no_args) { "new@example.com" }
101
101
  allow(Imap::Backup::Configuration::Account).to receive(:new).
102
- with(store, normal, anything).and_return(account)
103
-
104
- subject.run
102
+ with(store, normal, anything) { account }
105
103
  end
106
104
 
107
105
  it "edits the account" do
108
- expect(account).to have_received(:run)
106
+ expect(account).to receive(:run)
107
+
108
+ subject.run
109
109
  end
110
110
  end
111
111
 
@@ -125,9 +125,9 @@ describe Imap::Backup::Configuration::Setup do
125
125
  before do
126
126
  allow(input).to receive(:gets).and_return("add\n", "exit\n")
127
127
  allow(Imap::Backup::Configuration::Asker).to receive(:email).
128
- with(no_args).and_return("new@example.com")
128
+ with(no_args) { "new@example.com" }
129
129
  allow(Imap::Backup::Configuration::Account).to receive(:new).
130
- with(store, blank_account, anything).and_return(account)
130
+ with(store, blank_account, anything) { account }
131
131
 
132
132
  subject.run
133
133
  end
@@ -145,20 +145,25 @@ describe Imap::Backup::Configuration::Setup do
145
145
  context "when debug logging is disabled" do
146
146
  before do
147
147
  allow(input).to receive(:gets).and_return("start\n", "exit\n")
148
- subject.run
149
148
  end
150
149
 
151
150
  it "shows a menu item" do
151
+ subject.run
152
+
152
153
  expect(output.string).to include("start logging")
153
154
  end
154
155
 
155
156
  context "when selected" do
156
157
  it "sets the debug flag" do
157
- expect(store).to have_received(:debug=).with(true)
158
+ expect(store).to receive(:debug=).with(true)
159
+
160
+ subject.run
158
161
  end
159
162
 
160
163
  it "updates logging status" do
161
- expect(Imap::Backup).to have_received(:setup_logging).twice
164
+ expect(Imap::Backup).to receive(:setup_logging).twice
165
+
166
+ subject.run
162
167
  end
163
168
  end
164
169
  end
@@ -168,10 +173,11 @@ describe Imap::Backup::Configuration::Setup do
168
173
 
169
174
  before do
170
175
  allow(input).to receive(:gets).and_return("stop\n", "exit\n")
171
- subject.run
172
176
  end
173
177
 
174
178
  it "shows a menu item" do
179
+ subject.run
180
+
175
181
  expect(output.string).to include("stop logging")
176
182
  end
177
183
 
@@ -181,11 +187,15 @@ describe Imap::Backup::Configuration::Setup do
181
187
  end
182
188
 
183
189
  it "unsets the debug flag" do
184
- expect(store).to have_received(:debug=).with(false)
190
+ expect(store).to receive(:debug=).with(false)
191
+
192
+ subject.run
185
193
  end
186
194
 
187
195
  it "updates logging status" do
188
- expect(Imap::Backup).to have_received(:setup_logging).twice
196
+ expect(Imap::Backup).to receive(:setup_logging).twice
197
+
198
+ subject.run
189
199
  end
190
200
  end
191
201
  end
@@ -193,41 +203,46 @@ describe Imap::Backup::Configuration::Setup do
193
203
 
194
204
  context "when 'save' is selected" do
195
205
  before do
196
- allow(input).to receive(:gets).and_return("save\n")
197
- subject.run
206
+ allow(input).to receive(:gets) { "save\n" }
198
207
  end
199
208
 
200
209
  it "exits" do
201
210
  # N.B. this will hang forever if save does not cause an exit
211
+ subject.run
202
212
  end
203
213
 
204
214
  it "saves the configuration" do
205
- expect(store).to have_received(:save)
215
+ expect(store).to receive(:save)
216
+
217
+ subject.run
206
218
  end
207
219
  end
208
220
 
209
221
  context "when 'exit without saving' is selected" do
210
222
  before do
211
- allow(input).to receive(:gets).and_return("exit\n")
212
-
213
- subject.run
223
+ allow(input).to receive(:gets) { "exit\n" }
214
224
  end
215
225
 
216
226
  it "exits" do
217
227
  # N.B. this will hang forever if quit does not cause an exit
228
+ subject.run
218
229
  end
219
230
 
220
231
  context "when the configuration is modified" do
221
232
  let(:modified) { true }
222
233
 
223
234
  it "doesn't save the configuration" do
224
- expect(store).to_not have_received(:save)
235
+ expect(store).to_not receive(:save)
236
+
237
+ subject.run
225
238
  end
226
239
  end
227
240
 
228
241
  context "when the configuration isn't modified" do
229
242
  it "doesn't save the configuration" do
230
- expect(store).to_not have_received(:save)
243
+ expect(store).to_not receive(:save)
244
+
245
+ subject.run
231
246
  end
232
247
  end
233
248
  end