imap-backup 6.0.0.rc2 → 6.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (108) hide show
  1. checksums.yaml +4 -4
  2. data/imap-backup.gemspec +5 -1
  3. data/lib/cli_coverage.rb +11 -11
  4. data/lib/email/provider/base.rb +2 -0
  5. data/lib/email/provider/unknown.rb +2 -0
  6. data/lib/email/provider.rb +2 -0
  7. data/lib/imap/backup/account/connection/backup_folders.rb +27 -0
  8. data/lib/imap/backup/account/connection/client_factory.rb +54 -0
  9. data/lib/imap/backup/account/connection/folder_names.rb +26 -0
  10. data/lib/imap/backup/account/connection.rb +11 -95
  11. data/lib/imap/backup/account/folder.rb +9 -6
  12. data/lib/imap/backup/account.rb +3 -5
  13. data/lib/imap/backup/cli/backup.rb +1 -3
  14. data/lib/imap/backup/cli/helpers.rb +24 -22
  15. data/lib/imap/backup/cli/local.rb +20 -13
  16. data/lib/imap/backup/cli/migrate.rb +4 -10
  17. data/lib/imap/backup/cli/restore.rb +8 -7
  18. data/lib/imap/backup/cli/setup.rb +10 -8
  19. data/lib/imap/backup/cli/stats.rb +78 -0
  20. data/lib/imap/backup/cli/status.rb +2 -2
  21. data/lib/imap/backup/cli/utils.rb +4 -6
  22. data/lib/imap/backup/cli.rb +24 -3
  23. data/lib/imap/backup/configuration.rb +9 -11
  24. data/lib/imap/backup/downloader.rb +48 -30
  25. data/lib/imap/backup/migrator.rb +5 -5
  26. data/lib/imap/backup/sanitizer.rb +3 -2
  27. data/lib/imap/backup/serializer/appender.rb +49 -0
  28. data/lib/imap/backup/serializer/message_enumerator.rb +29 -0
  29. data/lib/imap/backup/serializer/unused_name_finder.rb +27 -0
  30. data/lib/imap/backup/serializer.rb +24 -78
  31. data/lib/imap/backup/setup/account/header.rb +75 -0
  32. data/lib/imap/backup/setup/account.rb +14 -91
  33. data/lib/imap/backup/setup/asker.rb +4 -15
  34. data/lib/imap/backup/setup/backup_path.rb +41 -0
  35. data/lib/imap/backup/setup/email.rb +45 -0
  36. data/lib/imap/backup/setup/folder_chooser.rb +3 -3
  37. data/lib/imap/backup/setup/helpers.rb +1 -1
  38. data/lib/imap/backup/setup.rb +5 -4
  39. data/lib/imap/backup/thunderbird/mailbox_exporter.rb +39 -20
  40. data/lib/imap/backup/uploader.rb +46 -8
  41. data/lib/imap/backup/utils.rb +1 -1
  42. data/lib/imap/backup/version.rb +1 -1
  43. data/lib/imap/backup.rb +0 -1
  44. metadata +31 -134
  45. data/spec/features/backup_spec.rb +0 -100
  46. data/spec/features/configuration/minimal_configuration.rb +0 -15
  47. data/spec/features/configuration/missing_configuration.rb +0 -14
  48. data/spec/features/folders_spec.rb +0 -36
  49. data/spec/features/helper.rb +0 -2
  50. data/spec/features/local/list_accounts_spec.rb +0 -12
  51. data/spec/features/local/list_emails_spec.rb +0 -21
  52. data/spec/features/local/list_folders_spec.rb +0 -21
  53. data/spec/features/local/show_an_email_spec.rb +0 -34
  54. data/spec/features/migrate_spec.rb +0 -35
  55. data/spec/features/remote/list_account_folders_spec.rb +0 -16
  56. data/spec/features/restore_spec.rb +0 -162
  57. data/spec/features/status_spec.rb +0 -43
  58. data/spec/features/support/aruba.rb +0 -78
  59. data/spec/features/support/backup_directory.rb +0 -43
  60. data/spec/features/support/email_server.rb +0 -110
  61. data/spec/features/support/shared/connection_context.rb +0 -14
  62. data/spec/features/support/shared/message_fixtures.rb +0 -16
  63. data/spec/fixtures/connection.yml +0 -7
  64. data/spec/spec_helper.rb +0 -15
  65. data/spec/support/fixtures.rb +0 -11
  66. data/spec/support/higline_test_helpers.rb +0 -8
  67. data/spec/support/silence_logging.rb +0 -7
  68. data/spec/unit/email/mboxrd/message_spec.rb +0 -177
  69. data/spec/unit/email/provider/apple_mail_spec.rb +0 -7
  70. data/spec/unit/email/provider/base_spec.rb +0 -11
  71. data/spec/unit/email/provider/fastmail_spec.rb +0 -7
  72. data/spec/unit/email/provider/gmail_spec.rb +0 -7
  73. data/spec/unit/email/provider_spec.rb +0 -27
  74. data/spec/unit/imap/backup/account/connection_spec.rb +0 -433
  75. data/spec/unit/imap/backup/account/folder_spec.rb +0 -261
  76. data/spec/unit/imap/backup/account_spec.rb +0 -246
  77. data/spec/unit/imap/backup/cli/accounts_spec.rb +0 -58
  78. data/spec/unit/imap/backup/cli/backup_spec.rb +0 -19
  79. data/spec/unit/imap/backup/cli/folders_spec.rb +0 -39
  80. data/spec/unit/imap/backup/cli/helpers_spec.rb +0 -87
  81. data/spec/unit/imap/backup/cli/local_spec.rb +0 -100
  82. data/spec/unit/imap/backup/cli/migrate_spec.rb +0 -80
  83. data/spec/unit/imap/backup/cli/restore_spec.rb +0 -67
  84. data/spec/unit/imap/backup/cli/setup_spec.rb +0 -17
  85. data/spec/unit/imap/backup/cli/utils_spec.rb +0 -125
  86. data/spec/unit/imap/backup/cli_spec.rb +0 -93
  87. data/spec/unit/imap/backup/client/apple_mail_spec.rb +0 -9
  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 -96
  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/sanitizer_spec.rb +0 -42
  94. data/spec/unit/imap/backup/serializer/directory_spec.rb +0 -37
  95. data/spec/unit/imap/backup/serializer/imap_spec.rb +0 -218
  96. data/spec/unit/imap/backup/serializer/mbox_enumerator_spec.rb +0 -45
  97. data/spec/unit/imap/backup/serializer/mbox_spec.rb +0 -101
  98. data/spec/unit/imap/backup/serializer_spec.rb +0 -296
  99. data/spec/unit/imap/backup/setup/account_spec.rb +0 -461
  100. data/spec/unit/imap/backup/setup/asker_spec.rb +0 -137
  101. data/spec/unit/imap/backup/setup/connection_tester_spec.rb +0 -51
  102. data/spec/unit/imap/backup/setup/folder_chooser_spec.rb +0 -146
  103. data/spec/unit/imap/backup/setup/helpers_spec.rb +0 -15
  104. data/spec/unit/imap/backup/setup_spec.rb +0 -301
  105. data/spec/unit/imap/backup/thunderbird/mailbox_exporter_spec.rb +0 -116
  106. data/spec/unit/imap/backup/uploader_spec.rb +0 -54
  107. data/spec/unit/imap/backup/utils_spec.rb +0 -92
  108. data/spec/unit/retry_on_error_spec.rb +0 -34
@@ -1,146 +0,0 @@
1
- describe Imap::Backup::Setup::FolderChooser do
2
- include HighLineTestHelpers
3
-
4
- describe "#run" do
5
- subject { described_class.new(account) }
6
-
7
- let(:connection) do
8
- instance_double(
9
- Imap::Backup::Account::Connection, folder_names: connection_folders
10
- )
11
- end
12
- let(:account) do
13
- instance_double(
14
- Imap::Backup::Account,
15
- folders: account_folders,
16
- "folders=": nil
17
- )
18
- end
19
- let(:account_folders) { [] }
20
- let(:connection_folders) { [] }
21
- let!(:highline_streams) { prepare_highline }
22
- let(:input) { highline_streams[0] }
23
- let(:output) { highline_streams[1] }
24
-
25
- before do
26
- allow(Imap::Backup::Account::Connection).to receive(:new) { connection }
27
- allow(Kernel).to receive(:system)
28
- allow(Imap::Backup::Logger.logger).to receive(:warn)
29
- end
30
-
31
- describe "display" do
32
- it "clears the screen" do
33
- expect(Kernel).to receive(:system).with("clear")
34
-
35
- subject.run
36
- end
37
-
38
- it "shows the menu" do
39
- subject.run
40
-
41
- expect(output.string).to match %r{Add/remove folders}
42
- end
43
- end
44
-
45
- describe "folder listing" do
46
- let(:account_folders) { [{name: "my_folder"}]}
47
- let(:connection_folders) do
48
- # N.B. my_folder is already backed up
49
- %w(my_folder another_folder)
50
- end
51
-
52
- describe "display" do
53
- before { subject.run }
54
-
55
- it "shows folders which are being backed up" do
56
- expect(output.string).to include("+ my_folder")
57
- end
58
-
59
- it "shows folders which are not being backed up" do
60
- expect(output.string).to include("- another_folder")
61
- end
62
- end
63
-
64
- context "when adding folders" do
65
- before do
66
- allow(input).to receive(:gets).and_return("2\n", "q\n")
67
-
68
- subject.run
69
- end
70
-
71
- specify "are added to the account" do
72
- expect(account).to have_received(:"folders=").
73
- with([{name: "my_folder"}, {name: "another_folder"}])
74
- end
75
- end
76
-
77
- context "when removing folders" do
78
- before do
79
- allow(input).to receive(:gets).and_return("1\n", "q\n")
80
-
81
- subject.run
82
- end
83
-
84
- specify "are removed from the account" do
85
- expect(account).to have_received(:"folders=").with([])
86
- end
87
- end
88
- end
89
-
90
- context "with missing remote folders" do
91
- let(:account_folders) do
92
- [{name: "on_server"}, {name: "not_on_server"}]
93
- end
94
- let(:connection_folders) { ["on_server"] }
95
-
96
- before do
97
- allow(Kernel).to receive(:puts)
98
- subject.run
99
- end
100
-
101
- specify "are removed from the account" do
102
- expect(account).to have_received(:"folders=").
103
- with([{name: "on_server"}])
104
- end
105
- end
106
-
107
- context "when folders are not available" do
108
- let(:connection_folders) { nil }
109
-
110
- before do
111
- allow(Imap::Backup::Setup.highline).
112
- to receive(:ask) { "q" }
113
- end
114
-
115
- it "asks to press a key" do
116
- expect(Imap::Backup::Setup.highline).
117
- to receive(:ask).with("Press a key ")
118
-
119
- subject.run
120
- end
121
- end
122
-
123
- context "with connection errors" do
124
- before do
125
- allow(Imap::Backup::Account::Connection).
126
- to receive(:new).with(account).and_raise("error")
127
- allow(Imap::Backup::Setup.highline).
128
- to receive(:ask) { "q" }
129
- end
130
-
131
- it "prints an error message" do
132
- expect(Imap::Backup::Logger.logger).
133
- to receive(:warn).with("Connection failed")
134
-
135
- subject.run
136
- end
137
-
138
- it "asks to continue" do
139
- expect(Imap::Backup::Setup.highline).
140
- to receive(:ask).with("Press a key ")
141
-
142
- subject.run
143
- end
144
- end
145
- end
146
- end
@@ -1,15 +0,0 @@
1
- module Imap::Backup
2
- RSpec.describe Setup::Helpers do
3
- describe "#title_prefix" do
4
- it "is a string" do
5
- expect(subject.title_prefix).to eq("imap-backup –")
6
- end
7
- end
8
-
9
- describe "#version" do
10
- it "is a version string" do
11
- expect(subject.version).to match(/\A\d+\.\d+\.\d+(\.\w+)?\z/)
12
- end
13
- end
14
- end
15
- end
@@ -1,301 +0,0 @@
1
- describe Imap::Backup::Setup do
2
- include HighLineTestHelpers
3
-
4
- subject { described_class.new }
5
-
6
- let(:normal_account) do
7
- instance_double(
8
- Imap::Backup::Account,
9
- username: "account@example.com",
10
- marked_for_deletion?: false,
11
- modified?: false
12
- )
13
- end
14
- let(:modified_account) do
15
- instance_double(
16
- Imap::Backup::Account,
17
- username: "modified@example.com",
18
- marked_for_deletion?: false,
19
- modified?: true
20
- )
21
- end
22
- let(:deleted_account) do
23
- instance_double(
24
- Imap::Backup::Account,
25
- username: "delete@example.com",
26
- marked_for_deletion?: true,
27
- modified?: false
28
- )
29
- end
30
- let(:accounts) { [normal_account] }
31
- let(:store) do
32
- instance_double(
33
- Imap::Backup::Configuration,
34
- "accounts": accounts,
35
- "path": "/base/path",
36
- "save": nil,
37
- "debug?": debug,
38
- "debug=": nil,
39
- "modified?": config_modified
40
- )
41
- end
42
- let(:debug) { false }
43
- let(:config_modified) { false }
44
- let!(:highline_streams) { prepare_highline }
45
- let(:input) { highline_streams[0] }
46
- let(:output) { highline_streams[1] }
47
- let(:gmail_imap_server) { "imap.gmail.com" }
48
-
49
- describe "#initialize" do
50
- context "without a config file" do
51
- it "works" do
52
- described_class.new
53
- end
54
- end
55
- end
56
-
57
- describe "#run" do
58
- before do
59
- allow(Imap::Backup::Configuration).to receive(:new) { store }
60
- allow(Imap::Backup::Logger).to receive(:setup_logging)
61
- allow(input).to receive(:eof?) { false }
62
- allow(input).to receive(:gets) { "q\n" }
63
- allow(Kernel).to receive(:system)
64
- end
65
-
66
- describe "main menu" do
67
- context "when changes have not been made" do
68
- before { subject.run }
69
-
70
- ["add account", "quit"].each do |choice|
71
- it "includes #{choice}" do
72
- expect(output.string).to include(choice)
73
- end
74
- end
75
- end
76
-
77
- context "when changes have been made" do
78
- let(:config_modified) { true }
79
-
80
- before do
81
- allow(input).to receive(:gets) { "exit\n" }
82
- subject.run
83
- end
84
-
85
- ["save and exit", "exit without saving"].each do |choice|
86
- it "includes '#{choice}'" do
87
- expect(output.string).to include(choice)
88
- end
89
- end
90
- end
91
- end
92
-
93
- it "clears the screen" do
94
- expect(Kernel).to receive(:system).with("clear")
95
-
96
- subject.run
97
- end
98
-
99
- describe "listing" do
100
- let(:accounts) { [normal_account, modified_account, deleted_account] }
101
-
102
- before { subject.run }
103
-
104
- describe "normal accounts" do
105
- it "are listed" do
106
- expect(output.string).to match(/account@example.com/)
107
- end
108
- end
109
-
110
- describe "modified accounts" do
111
- it "are flagged" do
112
- expect(output.string).to match(/modified@example.com \*/)
113
- end
114
- end
115
-
116
- describe "deleted accounts" do
117
- it "are hidden" do
118
- expect(output.string).to_not match(/delete@example.com/)
119
- end
120
- end
121
- end
122
-
123
- context "when editing accounts" do
124
- let(:account) do
125
- instance_double(Imap::Backup::Setup::Account, run: nil)
126
- end
127
- let(:config_modified) { true }
128
-
129
- before do
130
- allow(input).to receive(:gets).and_return("1\n", "exit\n")
131
- allow(Imap::Backup::Setup::Asker).to receive(:email).
132
- with(no_args) { "new@example.com" }
133
- allow(Imap::Backup::Setup::Account).to receive(:new).
134
- with(store, normal_account, anything) { account }
135
- end
136
-
137
- it "edits the account" do
138
- expect(account).to receive(:run)
139
-
140
- subject.run
141
- end
142
- end
143
-
144
- context "when adding accounts" do
145
- let(:blank_account) do
146
- {
147
- username: added_email,
148
- password: "",
149
- local_path: local_path,
150
- folders: []
151
- }
152
- end
153
- let(:account) do
154
- instance_double(Imap::Backup::Setup::Account, run: nil)
155
- end
156
- let(:config_modified) { true }
157
- let(:added_email) { "new@example.com" }
158
- let(:local_path) { "/base/path/new_example.com" }
159
-
160
- before do
161
- allow(input).to receive(:gets).and_return("add\n", "exit\n")
162
- allow(Imap::Backup::Setup::Asker).to receive(:email).
163
- with(no_args) { added_email }
164
- allow(Imap::Backup::Setup::Account).to receive(:new).
165
- with(store, anything, anything) { account }
166
-
167
- subject.run
168
- end
169
-
170
- it "sets username" do
171
- expect(accounts[1].username).to eq(added_email)
172
- end
173
-
174
- it "sets blank password" do
175
- expect(accounts[1].password).to eq("")
176
- end
177
-
178
- it "sets local_path" do
179
- expect(accounts[1].local_path).to eq(local_path)
180
- end
181
-
182
- it "sets folders" do
183
- expect(accounts[1].folders).to eq([])
184
- end
185
-
186
- context "when the account is a GMail account" do
187
- let(:added_email) { "new@gmail.com" }
188
- let(:local_path) { "/base/path/new_gmail.com" }
189
-
190
- it "sets the server" do
191
- expect(accounts[1].server).to eq(gmail_imap_server)
192
- end
193
- end
194
-
195
- it "doesn't flag the unedited account as modified" do
196
- expect(accounts[1].modified?).to be_falsey
197
- end
198
- end
199
-
200
- describe "logging" do
201
- context "when debug logging is disabled" do
202
- let(:config_modified) { true }
203
-
204
- before do
205
- allow(input).to receive(:gets).and_return("start\n", "exit\n")
206
- end
207
-
208
- it "shows a menu item" do
209
- subject.run
210
-
211
- expect(output.string).to include("start logging")
212
- end
213
-
214
- context "when selected" do
215
- it "sets the debug flag" do
216
- expect(store).to receive(:debug=).with(true)
217
-
218
- subject.run
219
- end
220
-
221
- it "updates logging status" do
222
- expect(Imap::Backup::Logger).to receive(:setup_logging)
223
-
224
- subject.run
225
- end
226
- end
227
- end
228
-
229
- context "when debug logging is enabled" do
230
- let(:debug) { true }
231
- let(:config_modified) { true }
232
-
233
- before do
234
- allow(input).to receive(:gets).and_return("stop\n", "exit\n")
235
- end
236
-
237
- it "shows a menu item" do
238
- subject.run
239
-
240
- expect(output.string).to include("stop logging")
241
- end
242
-
243
- context "when selected" do
244
- before do
245
- allow(input).to receive(:gets).and_return("stop\n", "exit\n")
246
- end
247
-
248
- it "unsets the debug flag" do
249
- expect(store).to receive(:debug=).with(false)
250
-
251
- subject.run
252
- end
253
-
254
- it "updates logging status" do
255
- expect(Imap::Backup::Logger).to receive(:setup_logging)
256
-
257
- subject.run
258
- end
259
- end
260
- end
261
- end
262
-
263
- context "when 'save' is selected" do
264
- let(:config_modified) { true }
265
-
266
- before do
267
- allow(input).to receive(:gets) { "save\n" }
268
- end
269
-
270
- it "exits" do
271
- # N.B. this will hang forever if save does not cause an exit
272
- subject.run
273
- end
274
-
275
- it "saves the configuration" do
276
- expect(store).to receive(:save)
277
-
278
- subject.run
279
- end
280
- end
281
-
282
- context "when 'exit without saving' is selected" do
283
- let(:config_modified) { true }
284
-
285
- before do
286
- allow(input).to receive(:gets) { "exit\n" }
287
- end
288
-
289
- it "exits" do
290
- # N.B. this will hang forever if quit does not cause an exit
291
- subject.run
292
- end
293
-
294
- it "doesn't save the configuration" do
295
- expect(store).to_not receive(:save)
296
-
297
- subject.run
298
- end
299
- end
300
- end
301
- end
@@ -1,116 +0,0 @@
1
- module Imap::Backup
2
- describe Thunderbird::MailboxExporter do
3
- subject { described_class.new("email", serializer, "profile", **args) }
4
-
5
- let(:args) { {} }
6
- let(:serializer) do
7
- instance_double(
8
- Serializer,
9
- folder: "folder",
10
- mbox_pathname: "mbox_pathname"
11
- )
12
- end
13
- let(:local_folder) do
14
- instance_double(
15
- Thunderbird::LocalFolder,
16
- exists?: local_folder_exists,
17
- full_path: "full_path",
18
- msf_exists?: msf_exists,
19
- msf_path: "msf_path",
20
- path: "path",
21
- set_up: set_up_result
22
- )
23
- end
24
- let(:local_folder_exists) { false }
25
- let(:msf_exists) { false }
26
- let(:set_up_result) { true }
27
- let(:file) { instance_double(File, write: nil) }
28
- let(:enumerator) { instance_double(Serializer::MboxEnumerator) }
29
-
30
- before do
31
- allow(File).to receive(:open).with("full_path", "w").and_yield(file)
32
- allow(File).to receive(:unlink)
33
- allow(Thunderbird::LocalFolder).to receive(:new) { local_folder }
34
- allow(Serializer::MboxEnumerator).to receive(:new) { enumerator }
35
- allow(enumerator).to receive(:each) { ["message"].enum_for(:each) }
36
- allow(Email::Mboxrd::Message).to receive(:clean_serialized) { "cleaned" }
37
- allow(Kernel).to receive(:puts)
38
- end
39
-
40
- describe "#run" do
41
- let!(:result) { subject.run }
42
-
43
- context "when the destination folder cannot be set up" do
44
- let(:set_up_result) { false }
45
-
46
- it "doesn't copy the mailbox" do
47
- expect(file).to_not have_received(:write)
48
- end
49
-
50
- it "returns false" do
51
- expect(result).to be false
52
- end
53
- end
54
-
55
- context "when the .msf file exists" do
56
- let(:msf_exists) { true }
57
-
58
- context "when 'force' is set" do
59
- let(:args) { {force: true} }
60
-
61
- it "deletes the file" do
62
- expect(File).to have_received(:unlink).with("msf_path")
63
- end
64
- end
65
-
66
- context "when 'force' isn't set" do
67
- it "doesn't copy the mailbox" do
68
- expect(file).to_not have_received(:write)
69
- end
70
-
71
- it "returns false" do
72
- expect(result).to be false
73
- end
74
- end
75
- end
76
-
77
- context "when the destination mailbox exists" do
78
- let(:local_folder_exists) { true }
79
-
80
- context "when 'force' is set" do
81
- let(:args) { {force: true} }
82
-
83
- it "writes the message" do
84
- expect(file).to have_received(:write)
85
- end
86
-
87
- it "returns true" do
88
- expect(result).to be true
89
- end
90
- end
91
-
92
- context "when 'force' isn't set" do
93
- it "doesn't copy the mailbox" do
94
- expect(file).to_not have_received(:write)
95
- end
96
-
97
- it "returns false" do
98
- expect(result).to be false
99
- end
100
- end
101
- end
102
-
103
- it "adds a 'From' line" do
104
- expect(file).to have_received(:write).with(/From - \w+ \w+ \d+ \d+:\d+:\d+/)
105
- end
106
-
107
- it "writes the cleaned message" do
108
- expect(file).to have_received(:write).with(/cleaned/)
109
- end
110
-
111
- it "returns true" do
112
- expect(result).to be true
113
- end
114
- end
115
- end
116
- end
@@ -1,54 +0,0 @@
1
- describe Imap::Backup::Uploader do
2
- subject { described_class.new(folder, serializer) }
3
-
4
- let(:folder) do
5
- instance_double(
6
- Imap::Backup::Account::Folder, uids: [2, 3], append: 99, name: "foo"
7
- )
8
- end
9
- let(:serializer) do
10
- instance_double(
11
- Imap::Backup::Serializer,
12
- uids: [1, 2],
13
- update_uid: nil
14
- )
15
- end
16
- let(:missing_message) do
17
- instance_double(Email::Mboxrd::Message, supplied_body: "missing message")
18
- end
19
- let(:existing_message) do
20
- instance_double(Email::Mboxrd::Message, supplied_body: "existing message")
21
- end
22
-
23
- def message_enumerator
24
- yield [1, missing_message]
25
- end
26
-
27
- describe "#run" do
28
- before do
29
- allow(serializer).to receive(:each_message).and_return(enum_for(:message_enumerator))
30
- end
31
-
32
- context "with messages that are missing" do
33
- it "restores them" do
34
- expect(folder).to receive(:append).with(missing_message)
35
-
36
- subject.run
37
- end
38
-
39
- it "updates the local message id" do
40
- expect(serializer).to receive(:update_uid).with(1, 99)
41
-
42
- subject.run
43
- end
44
- end
45
-
46
- context "with messages that are present on server" do
47
- it "does nothing" do
48
- expect(folder).to_not receive(:append).with(existing_message)
49
-
50
- subject.run
51
- end
52
- end
53
- end
54
- end