imap-backup 6.0.0.rc2 → 6.0.0

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