imap-backup 5.2.0 → 6.0.1

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 (102) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +9 -2
  3. data/docs/development.md +10 -4
  4. data/imap-backup.gemspec +5 -1
  5. data/lib/cli_coverage.rb +11 -11
  6. data/lib/email/provider/base.rb +2 -0
  7. data/lib/email/provider/unknown.rb +2 -0
  8. data/lib/email/provider.rb +2 -0
  9. data/lib/imap/backup/account/connection/backup_folders.rb +27 -0
  10. data/lib/imap/backup/account/connection/client_factory.rb +54 -0
  11. data/lib/imap/backup/account/connection/folder_names.rb +26 -0
  12. data/lib/imap/backup/account/connection.rb +17 -105
  13. data/lib/imap/backup/account/folder.rb +9 -6
  14. data/lib/imap/backup/account.rb +36 -16
  15. data/lib/imap/backup/cli/backup.rb +1 -3
  16. data/lib/imap/backup/cli/folders.rb +3 -3
  17. data/lib/imap/backup/cli/helpers.rb +24 -22
  18. data/lib/imap/backup/cli/local.rb +20 -13
  19. data/lib/imap/backup/cli/migrate.rb +5 -11
  20. data/lib/imap/backup/cli/restore.rb +8 -7
  21. data/lib/imap/backup/cli/setup.rb +10 -8
  22. data/lib/imap/backup/cli/stats.rb +78 -0
  23. data/lib/imap/backup/cli/status.rb +2 -2
  24. data/lib/imap/backup/cli/utils.rb +6 -8
  25. data/lib/imap/backup/cli.rb +24 -3
  26. data/lib/imap/backup/configuration.rb +9 -21
  27. data/lib/imap/backup/downloader.rb +56 -34
  28. data/lib/imap/backup/migrator.rb +5 -5
  29. data/lib/imap/backup/sanitizer.rb +3 -2
  30. data/lib/imap/backup/serializer/appender.rb +49 -0
  31. data/lib/imap/backup/serializer/directory.rb +37 -0
  32. data/lib/imap/backup/serializer/imap.rb +144 -0
  33. data/lib/imap/backup/serializer/mbox.rb +33 -88
  34. data/lib/imap/backup/serializer/mbox_enumerator.rb +2 -0
  35. data/lib/imap/backup/serializer/message_enumerator.rb +29 -0
  36. data/lib/imap/backup/serializer/unused_name_finder.rb +25 -0
  37. data/lib/imap/backup/serializer.rb +160 -3
  38. data/lib/imap/backup/setup/account/header.rb +75 -0
  39. data/lib/imap/backup/setup/account.rb +41 -95
  40. data/lib/imap/backup/setup/asker.rb +4 -15
  41. data/lib/imap/backup/setup/backup_path.rb +41 -0
  42. data/lib/imap/backup/setup/email.rb +45 -0
  43. data/lib/imap/backup/setup/folder_chooser.rb +3 -3
  44. data/lib/imap/backup/setup/helpers.rb +2 -2
  45. data/lib/imap/backup/setup.rb +5 -4
  46. data/lib/imap/backup/thunderbird/mailbox_exporter.rb +41 -22
  47. data/lib/imap/backup/uploader.rb +46 -8
  48. data/lib/imap/backup/utils.rb +1 -1
  49. data/lib/imap/backup/version.rb +3 -3
  50. data/lib/imap/backup.rb +0 -2
  51. metadata +31 -105
  52. data/lib/imap/backup/serializer/mbox_store.rb +0 -217
  53. data/spec/features/backup_spec.rb +0 -108
  54. data/spec/features/configuration/minimal_configuration.rb +0 -15
  55. data/spec/features/configuration/missing_configuration.rb +0 -14
  56. data/spec/features/folders_spec.rb +0 -36
  57. data/spec/features/helper.rb +0 -2
  58. data/spec/features/local/list_accounts_spec.rb +0 -12
  59. data/spec/features/local/list_emails_spec.rb +0 -21
  60. data/spec/features/local/list_folders_spec.rb +0 -21
  61. data/spec/features/local/show_an_email_spec.rb +0 -34
  62. data/spec/features/migrate_spec.rb +0 -35
  63. data/spec/features/remote/list_account_folders_spec.rb +0 -16
  64. data/spec/features/restore_spec.rb +0 -162
  65. data/spec/features/status_spec.rb +0 -43
  66. data/spec/features/support/aruba.rb +0 -77
  67. data/spec/features/support/backup_directory.rb +0 -43
  68. data/spec/features/support/email_server.rb +0 -110
  69. data/spec/features/support/shared/connection_context.rb +0 -14
  70. data/spec/features/support/shared/message_fixtures.rb +0 -16
  71. data/spec/fixtures/connection.yml +0 -7
  72. data/spec/spec_helper.rb +0 -15
  73. data/spec/support/fixtures.rb +0 -11
  74. data/spec/support/higline_test_helpers.rb +0 -8
  75. data/spec/support/silence_logging.rb +0 -7
  76. data/spec/unit/email/mboxrd/message_spec.rb +0 -177
  77. data/spec/unit/email/provider/apple_mail_spec.rb +0 -7
  78. data/spec/unit/email/provider/base_spec.rb +0 -11
  79. data/spec/unit/email/provider/fastmail_spec.rb +0 -7
  80. data/spec/unit/email/provider/gmail_spec.rb +0 -7
  81. data/spec/unit/email/provider_spec.rb +0 -27
  82. data/spec/unit/imap/backup/account/connection_spec.rb +0 -405
  83. data/spec/unit/imap/backup/account/folder_spec.rb +0 -251
  84. data/spec/unit/imap/backup/cli/accounts_spec.rb +0 -47
  85. data/spec/unit/imap/backup/cli/helpers_spec.rb +0 -87
  86. data/spec/unit/imap/backup/cli/local_spec.rb +0 -81
  87. data/spec/unit/imap/backup/cli/utils_spec.rb +0 -62
  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 -44
  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/serializer/mbox_enumerator_spec.rb +0 -45
  94. data/spec/unit/imap/backup/serializer/mbox_spec.rb +0 -222
  95. data/spec/unit/imap/backup/serializer/mbox_store_spec.rb +0 -329
  96. data/spec/unit/imap/backup/setup/account_spec.rb +0 -366
  97. data/spec/unit/imap/backup/setup/asker_spec.rb +0 -137
  98. data/spec/unit/imap/backup/setup/connection_tester_spec.rb +0 -51
  99. data/spec/unit/imap/backup/setup/folder_chooser_spec.rb +0 -146
  100. data/spec/unit/imap/backup/setup_spec.rb +0 -301
  101. data/spec/unit/imap/backup/uploader_spec.rb +0 -54
  102. data/spec/unit/imap/backup/utils_spec.rb +0 -92
@@ -1,238 +0,0 @@
1
- require "json"
2
- require "os"
3
-
4
- # rubocop:disable RSpec/PredicateMatcher
5
-
6
- describe Imap::Backup::Configuration do
7
- let(:directory) { "/base/path" }
8
- let(:file_path) { File.join(directory, "/config.json") }
9
- let(:file_exists) { true }
10
- let(:directory_exists) { true }
11
- let(:debug) { true }
12
- let(:configuration) { data.to_json }
13
- let(:data) { {debug: debug, accounts: accounts.map(&:to_h)} }
14
- let(:accounts) { [account1, account2] }
15
- let(:account1) { Imap::Backup::Account.new({username: "username1"}) }
16
- let(:account2) { Imap::Backup::Account.new({username: "username2"}) }
17
-
18
- before do
19
- stub_const(
20
- "Imap::Backup::Configuration::CONFIGURATION_DIRECTORY", directory
21
- )
22
- allow(File).to receive(:directory?).with(directory) { directory_exists }
23
- allow(File).to receive(:exist?).and_call_original
24
- allow(File).to receive(:exist?).with(file_path) { file_exists }
25
- allow(Imap::Backup::Utils).
26
- to receive(:stat).with(directory) { 0o700 }
27
- allow(Imap::Backup::Utils).
28
- to receive(:stat).with(file_path) { 0o600 }
29
- allow(Imap::Backup::Utils).to receive(:check_permissions) { nil }
30
- allow(File).to receive(:read).with(file_path) { configuration }
31
- end
32
-
33
- describe ".exist?" do
34
- [true, false].each do |exists|
35
- state = exists ? "exists" : "doesn't exist"
36
- context "when the file #{state}" do
37
- let(:file_exists) { exists }
38
-
39
- it "returns #{exists}" do
40
- expect(described_class.exist?).to eq(file_exists)
41
- end
42
- end
43
- end
44
- end
45
-
46
- describe "#path" do
47
- it "is the directory containing the configuration file" do
48
- expect(subject.path).to eq(directory)
49
- end
50
- end
51
-
52
- describe "#modified?" do
53
- context "with modified accounts" do
54
- before { subject.accounts[0].username = "changed" }
55
-
56
- it "is true" do
57
- expect(subject.modified?).to be_truthy
58
- end
59
- end
60
-
61
- context "with accounts flagged 'delete'" do
62
- before { subject.accounts[0].mark_for_deletion! }
63
-
64
- it "is true" do
65
- expect(subject.modified?).to be_truthy
66
- end
67
- end
68
-
69
- context "without accounts flagged 'modified'" do
70
- it "is false" do
71
- expect(subject.modified?).to be_falsey
72
- end
73
- end
74
- end
75
-
76
- describe "#debug?" do
77
- context "when the debug flag is true" do
78
- it "is true" do
79
- expect(subject.debug?).to be_truthy
80
- end
81
- end
82
-
83
- context "when the debug flag is false" do
84
- let(:debug) { false }
85
-
86
- it "is false" do
87
- expect(subject.debug?).to be_falsey
88
- end
89
- end
90
-
91
- context "when the debug flag is missing" do
92
- let(:data) { {accounts: accounts} }
93
-
94
- it "is false" do
95
- expect(subject.debug?).to be_falsey
96
- end
97
- end
98
-
99
- context "when the debug flag is neither true nor false" do
100
- let(:debug) { "hi" }
101
-
102
- it "is false" do
103
- expect(subject.debug?).to be_falsey
104
- end
105
- end
106
- end
107
-
108
- describe "#debug=" do
109
- before { subject.debug = debug }
110
-
111
- context "when the supplied value is true" do
112
- it "sets the flag to true" do
113
- expect(subject.debug?).to be_truthy
114
- end
115
- end
116
-
117
- context "when the supplied value is false" do
118
- let(:debug) { false }
119
-
120
- it "sets the flag to false" do
121
- expect(subject.debug?).to be_falsey
122
- end
123
- end
124
-
125
- context "when the supplied value is neither true nor false" do
126
- let(:debug) { "ciao" }
127
-
128
- it "sets the flag to false" do
129
- expect(subject.debug?).to be_falsey
130
- end
131
- end
132
- end
133
-
134
- describe "#save" do
135
- subject { described_class.new }
136
-
137
- let(:directory_exists) { false }
138
- let(:file) { instance_double(File, write: nil) }
139
-
140
- before do
141
- allow(FileUtils).to receive(:mkdir)
142
- allow(FileUtils).to receive(:chmod)
143
- allow(File).to receive(:open).with(file_path, "w").and_yield(file)
144
- allow(JSON).to receive(:pretty_generate) { "JSON output" }
145
- end
146
-
147
- it "creates the config directory" do
148
- expect(FileUtils).to receive(:mkdir).with(directory)
149
-
150
- subject.save
151
- end
152
-
153
- it "saves the configuration" do
154
- expect(file).to receive(:write).with("JSON output")
155
-
156
- subject.save
157
- end
158
-
159
- it "uses the Account#to_h method" do
160
- allow(subject.accounts[0]).to receive(:to_h) { "Account1" }
161
- allow(subject.accounts[1]).to receive(:to_h) { "Account2" }
162
-
163
- expect(JSON).to receive(:pretty_generate).
164
- with(hash_including({accounts: ["Account1", "Account2"]}))
165
-
166
- subject.save
167
- end
168
-
169
- context "when accounts are to be deleted" do
170
- let(:accounts) do
171
- [
172
- {name: "keep_me"},
173
- {name: "delete_me", delete: true}
174
- ]
175
- end
176
-
177
- before do
178
- allow(subject.accounts[0]).to receive(:to_h) { "Account1" }
179
- allow(subject.accounts[1]).to receive(:to_h) { "Account2" }
180
- subject.accounts[0].mark_for_deletion!
181
- end
182
-
183
- it "does not save them" do
184
- expect(JSON).to receive(:pretty_generate).
185
- with(hash_including({accounts: ["Account2"]}))
186
-
187
- subject.save
188
- end
189
- end
190
-
191
- context "when file permissions are too open" do
192
- context "when on UNIX" do
193
- before do
194
- allow(OS).to receive(:windows?) { false }
195
- end
196
-
197
- it "sets them to 0600" do
198
- expect(FileUtils).to receive(:chmod).with(0o600, file_path)
199
-
200
- subject.save
201
- end
202
- end
203
- end
204
-
205
- context "when the configuration file is missing" do
206
- let(:file_exists) { false }
207
-
208
- it "doesn't fail" do
209
- expect do
210
- subject.save
211
- end.to_not raise_error
212
- end
213
- end
214
-
215
- context "when on UNIX" do
216
- before do
217
- allow(OS).to receive(:windows?) { false }
218
- end
219
-
220
- context "when the config file permissions are too lax" do
221
- let(:file_exists) { true }
222
-
223
- before do
224
- allow(Imap::Backup::Utils).to receive(:check_permissions).
225
- with(file_path, 0o600).and_raise("Error")
226
- end
227
-
228
- it "fails" do
229
- expect do
230
- subject.save
231
- end.to raise_error(RuntimeError, "Error")
232
- end
233
- end
234
- end
235
- end
236
- end
237
-
238
- # rubocop:enable RSpec/PredicateMatcher
@@ -1,44 +0,0 @@
1
- describe Imap::Backup::Downloader do
2
- describe "#run" do
3
- subject { described_class.new(folder, serializer) }
4
-
5
- let(:body) { "blah" }
6
- let(:folder) do
7
- instance_double(
8
- Imap::Backup::Account::Folder,
9
- fetch_multi: [{uid: "111", body: body}],
10
- name: "folder",
11
- uids: folder_uids
12
- )
13
- end
14
- let(:folder_uids) { %w(111 222 333) }
15
- let(:serializer) do
16
- instance_double(Imap::Backup::Serializer::Mbox, save: nil, uids: ["222"])
17
- end
18
-
19
- context "with fetched messages" do
20
- specify "are saved" do
21
- expect(serializer).to receive(:save).with("111", body)
22
-
23
- subject.run
24
- end
25
- end
26
-
27
- context "with messages which are already present" do
28
- specify "are skipped" do
29
- expect(serializer).to_not receive(:save).with("222", anything)
30
-
31
- subject.run
32
- end
33
- end
34
-
35
- context "with failed fetches" do
36
- specify "are skipped" do
37
- allow(folder).to receive(:fetch_multi) { nil }
38
- expect(serializer).to_not receive(:save)
39
-
40
- subject.run
41
- end
42
- end
43
- end
44
- end
@@ -1,48 +0,0 @@
1
- require "net/imap"
2
-
3
- module Imap::Backup
4
- describe Logger do
5
- describe ".setup_logging" do
6
- let(:config) { instance_double(Configuration, debug?: debug) }
7
-
8
- around do |example|
9
- logger_previous = described_class.logger.level
10
- net_imap_previous = Net::IMAP.debug
11
- described_class.logger.level = 42
12
- Net::IMAP.debug = 42
13
- example.run
14
- Net::IMAP.debug = net_imap_previous
15
- described_class.logger.level = logger_previous
16
- end
17
-
18
- before do
19
- allow(Configuration).to receive(:new) { config }
20
- described_class.setup_logging
21
- end
22
-
23
- context "when config.debug?" do
24
- let(:debug) { true }
25
-
26
- it "sets logger level to debug" do
27
- expect(described_class.logger.level).to eq(::Logger::Severity::DEBUG)
28
- end
29
-
30
- it "sets the Net::IMAP debug flag" do
31
- expect(Net::IMAP.debug).to be_a(TrueClass)
32
- end
33
- end
34
-
35
- context "when not config.debug?" do
36
- let(:debug) { false }
37
-
38
- it "sets logger level to error" do
39
- expect(described_class.logger.level).to eq(::Logger::Severity::ERROR)
40
- end
41
-
42
- it "doesn't set the Net::IMAP debug flag" do
43
- expect(Net::IMAP.debug).to be_a(FalseClass)
44
- end
45
- end
46
- end
47
- end
48
- end
@@ -1,58 +0,0 @@
1
- require "imap/backup/migrator"
2
-
3
- module Imap::Backup
4
- RSpec.describe Migrator do
5
- subject { described_class.new(serializer, folder, reset: reset) }
6
-
7
- let(:serializer) { instance_double(Serializer::MboxStore, uids: [1]) }
8
- let(:folder) do
9
- instance_double(
10
- Account::Folder,
11
- append: nil, clear: nil, create: nil, name: "name", uids: folder_uids
12
- )
13
- end
14
- let(:folder_uids) { [] }
15
- let(:reset) { false }
16
- let(:messages) { [[1, message]] }
17
- let(:message) { instance_double(Email::Mboxrd::Message, supplied_body: body) }
18
- let(:body) { "body" }
19
-
20
- before do
21
- allow(serializer).to receive(:each_message) do
22
- messages.enum_for(:each)
23
- end
24
- end
25
-
26
- it "creates the folder" do
27
- subject.run
28
-
29
- expect(folder).to have_received(:create)
30
- end
31
-
32
- it "uploads messages" do
33
- subject.run
34
-
35
- expect(folder).to have_received(:append).with(message)
36
- end
37
-
38
- context "when the folder is not empty" do
39
- let(:folder_uids) { [99] }
40
-
41
- it "fails" do
42
- expect do
43
- subject.run
44
- end.to raise_error(RuntimeError, /The destination folder 'name' is not empty/)
45
- end
46
-
47
- context "when `reset` is true" do
48
- let(:reset) { true }
49
-
50
- it "clears the folder" do
51
- subject.run
52
-
53
- expect(folder).to have_received(:clear)
54
- end
55
- end
56
- end
57
- end
58
- end
@@ -1,45 +0,0 @@
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,222 +0,0 @@
1
- describe Imap::Backup::Serializer::Mbox do
2
- subject { described_class.new(base_path, imap_folder) }
3
-
4
- let(:base_path) { "/base/path" }
5
- let(:store) do
6
- instance_double(
7
- Imap::Backup::Serializer::MboxStore,
8
- add: nil,
9
- rename: nil,
10
- uids: nil,
11
- uid_validity: existing_uid_validity,
12
- "uid_validity=": nil,
13
- update_uid: nil
14
- )
15
- end
16
- let(:imap_folder) { "folder" }
17
- let(:permissions) { 0o700 }
18
- let(:dir_exists) { true }
19
- let(:existing_uid_validity) { nil }
20
-
21
- before do
22
- allow(Imap::Backup::Utils).to receive(:make_folder)
23
- allow(Imap::Backup::Utils).to receive(:mode) { permissions }
24
- allow(Imap::Backup::Utils).to receive(:check_permissions) { true }
25
- allow(File).to receive(:directory?) { dir_exists }
26
- allow(FileUtils).to receive(:chmod)
27
- allow(Imap::Backup::Serializer::MboxStore).to receive(:new) { store }
28
- end
29
-
30
- describe "folder path" do
31
- context "when it has multiple elements" do
32
- let(:imap_folder) { "folder/path" }
33
-
34
- context "when the containing directory is missing" do
35
- let(:dir_exists) { false }
36
-
37
- it "is created" do
38
- expect(Imap::Backup::Utils).to receive(:make_folder).
39
- with(base_path, File.dirname(imap_folder), 0o700)
40
-
41
- subject.uids
42
- end
43
- end
44
- end
45
-
46
- context "when permissions are incorrect" do
47
- let(:permissions) { 0o777 }
48
-
49
- it "corrects them" do
50
- path = File.expand_path(File.join(base_path, File.dirname(imap_folder)))
51
- expect(FileUtils).to receive(:chmod).with(0o700, path)
52
-
53
- subject.uids
54
- end
55
- end
56
-
57
- context "when permissons are correct" do
58
- it "does nothing" do
59
- expect(FileUtils).to_not receive(:chmod)
60
-
61
- subject.uids
62
- end
63
- end
64
-
65
- context "when it exists" do
66
- it "is not created" do
67
- expect(Imap::Backup::Utils).to_not receive(:make_folder).
68
- with(base_path, File.dirname(imap_folder), 0o700)
69
-
70
- subject.uids
71
- end
72
- end
73
- end
74
-
75
- describe "#apply_uid_validity" do
76
- context "when the existing uid validity is unset" do
77
- it "sets uid validity" do
78
- expect(store).to receive(:uid_validity=).with("aaa")
79
-
80
- subject.apply_uid_validity("aaa")
81
- end
82
-
83
- it "does not rename the store" do
84
- expect(store).to_not receive(:rename)
85
-
86
- subject.apply_uid_validity("aaa")
87
- end
88
-
89
- it "returns nil" do
90
- expect(subject.apply_uid_validity("aaa")).to be_nil
91
- end
92
- end
93
-
94
- context "when the uid validity is unchanged" do
95
- let(:existing_uid_validity) { "aaa" }
96
-
97
- it "does not set uid validity" do
98
- expect(store).to_not receive(:uid_validity=)
99
-
100
- subject.apply_uid_validity("aaa")
101
- end
102
-
103
- it "does not rename the store" do
104
- expect(store).to_not receive(:rename)
105
-
106
- subject.apply_uid_validity("aaa")
107
- end
108
-
109
- it "returns nil" do
110
- expect(subject.apply_uid_validity("aaa")).to be_nil
111
- end
112
- end
113
-
114
- context "when the uid validity is changed" do
115
- let(:existing_uid_validity) { "bbb" }
116
- let(:existing_store) do
117
- instance_double(Imap::Backup::Serializer::MboxStore)
118
- end
119
- let(:exists) { false }
120
-
121
- before do
122
- allow(Imap::Backup::Serializer::MboxStore).
123
- to receive(:new).with(anything, /bbb/) { existing_store }
124
- allow(existing_store).to receive(:exist?).and_return(exists, false)
125
- end
126
-
127
- it "sets uid validity" do
128
- expect(store).to receive(:uid_validity=).with("aaa")
129
-
130
- subject.apply_uid_validity("aaa")
131
- end
132
-
133
- context "when adding the uid validity does not cause a name clash" do
134
- it "renames the store, adding the existing uid validity" do
135
- expect(store).to receive(:rename).with("folder-bbb")
136
-
137
- subject.apply_uid_validity("aaa")
138
- end
139
-
140
- it "returns the new name" do
141
- expect(subject.apply_uid_validity("aaa")).to eq("folder-bbb")
142
- end
143
- end
144
-
145
- context "when adding the uid validity causes a name clash" do
146
- let(:exists) { true }
147
-
148
- it "renames the store, adding the existing uid validity and a digit" do
149
- expect(store).to receive(:rename).with("folder-bbb-1")
150
-
151
- subject.apply_uid_validity("aaa")
152
- end
153
-
154
- it "returns the new name" do
155
- expect(subject.apply_uid_validity("aaa")).to eq("folder-bbb-1")
156
- end
157
- end
158
- end
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
222
- end