imap-backup 4.0.5 → 4.0.6
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.
- checksums.yaml +4 -4
- data/lib/imap/backup/account/connection.rb +23 -31
- data/lib/imap/backup/account/folder.rb +1 -1
- data/lib/imap/backup/account.rb +2 -7
- data/lib/imap/backup/cli/helpers.rb +1 -1
- data/lib/imap/backup/cli/local.rb +1 -1
- data/lib/imap/backup/configuration/account.rb +37 -29
- data/lib/imap/backup/configuration/folder_chooser.rb +7 -9
- data/lib/imap/backup/configuration/setup.rb +10 -8
- data/lib/imap/backup/configuration/store.rb +33 -11
- data/lib/imap/backup/version.rb +1 -1
- data/spec/features/support/shared/connection_context.rb +7 -5
- data/spec/unit/email/provider/base_spec.rb +1 -1
- data/spec/unit/email/provider_spec.rb +2 -2
- data/spec/unit/imap/backup/account/connection_spec.rb +8 -17
- data/spec/unit/imap/backup/cli/local_spec.rb +9 -2
- data/spec/unit/imap/backup/cli/utils_spec.rb +44 -42
- data/spec/unit/imap/backup/configuration/account_spec.rb +47 -46
- data/spec/unit/imap/backup/configuration/folder_chooser_spec.rb +17 -18
- data/spec/unit/imap/backup/configuration/setup_spec.rb +33 -12
- data/spec/unit/imap/backup/configuration/store_spec.rb +21 -22
- metadata +1 -3
- data/spec/support/shared_examples/account_flagging.rb +0 -23
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7b543b8f8b913b95b68c9ad9532143c375d90b468b0977982faa3522c0d3932b
|
4
|
+
data.tar.gz: '0939b42c8dad41d14212a18444d94c209ce025646683faded89b9808e6181416'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 52f9058554faa9a3d31bef3cb7254408032cdddee98293ea5f7c8ef108d3187b564b7fd71a18bdb1b31829b46ed22bdd51626704f82e98d88076bd4cec887d44
|
7
|
+
data.tar.gz: 186036e2f11ed8e0ae578ab44d73b2b4c1f89bf9c65eedc66a143b4d1b861adacba1d954190d566c399cc79184ba3645ebb53a3341ee82a03ad9b5d5d7fa777d
|
@@ -4,25 +4,17 @@ require "imap/backup/client/default"
|
|
4
4
|
require "retry_on_error"
|
5
5
|
|
6
6
|
module Imap::Backup
|
7
|
-
|
7
|
+
class Account; end
|
8
8
|
|
9
9
|
class Account::Connection
|
10
10
|
include RetryOnError
|
11
11
|
|
12
12
|
LOGIN_RETRY_CLASSES = [EOFError, Errno::ECONNRESET, SocketError].freeze
|
13
13
|
|
14
|
-
attr_reader :
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
def initialize(options)
|
20
|
-
@username = options[:username]
|
21
|
-
@password = options[:password]
|
22
|
-
@local_path = options[:local_path]
|
23
|
-
@config_folders = options[:folders]
|
24
|
-
@server = options[:server]
|
25
|
-
@connection_options = options[:connection_options] || {}
|
14
|
+
attr_reader :account
|
15
|
+
|
16
|
+
def initialize(account)
|
17
|
+
@account = account
|
26
18
|
@folders = nil
|
27
19
|
create_account_folder
|
28
20
|
end
|
@@ -33,7 +25,7 @@ module Imap::Backup
|
|
33
25
|
folders = client.list
|
34
26
|
|
35
27
|
if folders.empty?
|
36
|
-
message = "Unable to get folder list for account #{username}"
|
28
|
+
message = "Unable to get folder list for account #{account.username}"
|
37
29
|
Imap::Backup.logger.info message
|
38
30
|
raise message
|
39
31
|
end
|
@@ -45,13 +37,13 @@ module Imap::Backup
|
|
45
37
|
def status
|
46
38
|
backup_folders.map do |backup_folder|
|
47
39
|
f = Account::Folder.new(self, backup_folder[:name])
|
48
|
-
s = Serializer::Mbox.new(local_path, backup_folder[:name])
|
40
|
+
s = Serializer::Mbox.new(account.local_path, backup_folder[:name])
|
49
41
|
{name: backup_folder[:name], local: s.uids, remote: f.uids}
|
50
42
|
end
|
51
43
|
end
|
52
44
|
|
53
45
|
def run_backup
|
54
|
-
Imap::Backup.logger.debug "Running backup of account: #{username}"
|
46
|
+
Imap::Backup.logger.debug "Running backup of account: #{account.username}"
|
55
47
|
# start the connection so we get logging messages in the right order
|
56
48
|
client
|
57
49
|
each_folder do |folder, serializer|
|
@@ -71,11 +63,11 @@ module Imap::Backup
|
|
71
63
|
def local_folders
|
72
64
|
return enum_for(:local_folders) if !block_given?
|
73
65
|
|
74
|
-
glob = File.join(local_path, "**", "*.imap")
|
75
|
-
base = Pathname.new(local_path)
|
66
|
+
glob = File.join(account.local_path, "**", "*.imap")
|
67
|
+
base = Pathname.new(account.local_path)
|
76
68
|
Pathname.glob(glob) do |path|
|
77
69
|
name = path.relative_path_from(base).to_s[0..-6]
|
78
|
-
serializer = Serializer::Mbox.new(local_path, name)
|
70
|
+
serializer = Serializer::Mbox.new(account.local_path, name)
|
79
71
|
folder = Account::Folder.new(self, name)
|
80
72
|
yield serializer, folder
|
81
73
|
end
|
@@ -109,15 +101,15 @@ module Imap::Backup
|
|
109
101
|
else
|
110
102
|
Client::Default.new(server, options)
|
111
103
|
end
|
112
|
-
Imap::Backup.logger.debug "Logging in: #{username}/#{masked_password}"
|
113
|
-
client.login(username, password)
|
104
|
+
Imap::Backup.logger.debug "Logging in: #{account.username}/#{masked_password}"
|
105
|
+
client.login(account.username, account.password)
|
114
106
|
Imap::Backup.logger.debug "Login complete"
|
115
107
|
client
|
116
108
|
end
|
117
109
|
end
|
118
110
|
|
119
111
|
def server
|
120
|
-
@server ||= provider.host
|
112
|
+
@server ||= account.server || provider.host
|
121
113
|
end
|
122
114
|
|
123
115
|
private
|
@@ -125,7 +117,7 @@ module Imap::Backup
|
|
125
117
|
def each_folder
|
126
118
|
backup_folders.each do |backup_folder|
|
127
119
|
folder = Account::Folder.new(self, backup_folder[:name])
|
128
|
-
serializer = Serializer::Mbox.new(local_path, backup_folder[:name])
|
120
|
+
serializer = Serializer::Mbox.new(account.local_path, backup_folder[:name])
|
129
121
|
yield folder, serializer
|
130
122
|
end
|
131
123
|
end
|
@@ -142,7 +134,7 @@ module Imap::Backup
|
|
142
134
|
Imap::Backup.logger.debug(
|
143
135
|
"Backup '#{old_name}' renamed and restored to '#{new_name}'"
|
144
136
|
)
|
145
|
-
new_serializer = Serializer::Mbox.new(local_path, new_name)
|
137
|
+
new_serializer = Serializer::Mbox.new(account.local_path, new_name)
|
146
138
|
new_folder = Account::Folder.new(self, new_name)
|
147
139
|
new_folder.create
|
148
140
|
new_serializer.force_uid_validity(new_folder.uid_validity)
|
@@ -159,21 +151,21 @@ module Imap::Backup
|
|
159
151
|
|
160
152
|
def create_account_folder
|
161
153
|
Utils.make_folder(
|
162
|
-
File.dirname(local_path),
|
163
|
-
File.basename(local_path),
|
154
|
+
File.dirname(account.local_path),
|
155
|
+
File.basename(account.local_path),
|
164
156
|
Serializer::DIRECTORY_PERMISSIONS
|
165
157
|
)
|
166
158
|
end
|
167
159
|
|
168
160
|
def masked_password
|
169
|
-
password.gsub(/./, "x")
|
161
|
+
account.password.gsub(/./, "x")
|
170
162
|
end
|
171
163
|
|
172
164
|
def backup_folders
|
173
165
|
@backup_folders ||=
|
174
166
|
begin
|
175
|
-
if
|
176
|
-
|
167
|
+
if account.folders&.any?
|
168
|
+
account.folders
|
177
169
|
else
|
178
170
|
folders.map { |name| {name: name} }
|
179
171
|
end
|
@@ -181,11 +173,11 @@ module Imap::Backup
|
|
181
173
|
end
|
182
174
|
|
183
175
|
def provider
|
184
|
-
@provider ||= Email::Provider.for_address(username)
|
176
|
+
@provider ||= Email::Provider.for_address(account.username)
|
185
177
|
end
|
186
178
|
|
187
179
|
def provider_options
|
188
|
-
provider.options.merge(connection_options)
|
180
|
+
provider.options.merge(account.connection_options || {})
|
189
181
|
end
|
190
182
|
end
|
191
183
|
end
|
data/lib/imap/backup/account.rb
CHANGED
@@ -83,14 +83,9 @@ module Imap::Backup
|
|
83
83
|
def update(field, value)
|
84
84
|
if changes[field]
|
85
85
|
change = changes[field]
|
86
|
-
if change[:from] == value
|
87
|
-
changes.delete(field)
|
88
|
-
else
|
89
|
-
set_field!(field, value)
|
90
|
-
end
|
91
|
-
else
|
92
|
-
set_field!(field, value)
|
86
|
+
changes.delete(field) if change[:from] == value
|
93
87
|
end
|
88
|
+
set_field!(field, value)
|
94
89
|
end
|
95
90
|
|
96
91
|
def set_field!(field, value)
|
@@ -7,7 +7,7 @@ module Imap::Backup::CLI::Helpers
|
|
7
7
|
|
8
8
|
def account(email)
|
9
9
|
connections = Imap::Backup::Configuration::List.new
|
10
|
-
account = connections.accounts.find { |a| a
|
10
|
+
account = connections.accounts.find { |a| a.username == email }
|
11
11
|
raise "#{email} is not a configured account" if !account
|
12
12
|
|
13
13
|
account
|
@@ -6,7 +6,7 @@ module Imap::Backup
|
|
6
6
|
desc "accounts", "List locally backed-up accounts"
|
7
7
|
def accounts
|
8
8
|
connections = Imap::Backup::Configuration::List.new
|
9
|
-
connections.accounts.each { |a| Kernel.puts a
|
9
|
+
connections.accounts.each { |a| Kernel.puts a.username }
|
10
10
|
end
|
11
11
|
|
12
12
|
desc "folders EMAIL", "List account folders"
|
@@ -22,9 +22,10 @@ module Imap::Backup
|
|
22
22
|
header menu
|
23
23
|
modify_email menu
|
24
24
|
modify_password menu
|
25
|
-
modify_server menu
|
26
25
|
modify_backup_path menu
|
27
26
|
choose_folders menu
|
27
|
+
modify_server menu
|
28
|
+
modify_connection_options menu
|
28
29
|
test_connection menu
|
29
30
|
delete_account menu
|
30
31
|
menu.choice("return to main menu") { throw :done }
|
@@ -33,13 +34,20 @@ module Imap::Backup
|
|
33
34
|
end
|
34
35
|
|
35
36
|
def header(menu)
|
36
|
-
|
37
|
+
connection_options =
|
38
|
+
if account.connection_options
|
39
|
+
escaped =
|
40
|
+
JSON.generate(account.connection_options).
|
41
|
+
gsub('"', '\"')
|
42
|
+
"\n connection options: #{escaped}"
|
43
|
+
end
|
44
|
+
menu.header = <<~HEADER
|
37
45
|
Account:
|
38
|
-
email: #{account
|
39
|
-
server: #{account[:server]}
|
40
|
-
path: #{account[:local_path]}
|
41
|
-
folders: #{folders.map { |f| f[:name] }.join(', ')}
|
46
|
+
email: #{account.username}
|
42
47
|
password: #{masked_password}
|
48
|
+
path: #{account.local_path}
|
49
|
+
folders: #{folders.map { |f| f[:name] }.join(', ')}
|
50
|
+
server: #{account.server}#{connection_options}
|
43
51
|
HEADER
|
44
52
|
end
|
45
53
|
|
@@ -48,20 +56,20 @@ module Imap::Backup
|
|
48
56
|
username = Configuration::Asker.email(username)
|
49
57
|
Kernel.puts "username: #{username}"
|
50
58
|
other_accounts = store.accounts.reject { |a| a == account }
|
51
|
-
others = other_accounts.map { |a| a
|
59
|
+
others = other_accounts.map { |a| a.username }
|
52
60
|
Kernel.puts "others: #{others.inspect}"
|
53
61
|
if others.include?(username)
|
54
62
|
Kernel.puts(
|
55
63
|
"There is already an account set up with that email address"
|
56
64
|
)
|
57
65
|
else
|
58
|
-
account
|
66
|
+
account.username = username
|
59
67
|
# rubocop:disable Style/IfUnlessModifier
|
60
|
-
|
61
|
-
|
68
|
+
default = default_server(username)
|
69
|
+
if default && (account.server.nil? || (account.server == ""))
|
70
|
+
account.server = default
|
62
71
|
end
|
63
72
|
# rubocop:enable Style/IfUnlessModifier
|
64
|
-
account[:modified] = true
|
65
73
|
end
|
66
74
|
end
|
67
75
|
end
|
@@ -70,30 +78,31 @@ module Imap::Backup
|
|
70
78
|
menu.choice("modify password") do
|
71
79
|
password = Configuration::Asker.password
|
72
80
|
|
73
|
-
if !password.nil?
|
74
|
-
account[:password] = password
|
75
|
-
account[:modified] = true
|
76
|
-
end
|
81
|
+
account.password = password if !password.nil?
|
77
82
|
end
|
78
83
|
end
|
79
84
|
|
80
85
|
def modify_server(menu)
|
81
86
|
menu.choice("modify server") do
|
82
87
|
server = highline.ask("server: ")
|
83
|
-
if !server.nil?
|
84
|
-
|
85
|
-
|
86
|
-
|
88
|
+
account.server = server if !server.nil?
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def modify_connection_options(menu)
|
93
|
+
menu.choice("modify connection options") do
|
94
|
+
connection_options = highline.ask("connections options (as JSON): ")
|
95
|
+
account.connection_options = connection_options if !connection_options.nil?
|
87
96
|
end
|
88
97
|
end
|
89
98
|
|
90
99
|
def path_modification_validator(path)
|
91
100
|
same = store.accounts.find do |a|
|
92
|
-
a
|
101
|
+
a.username != account.username && a.local_path == path
|
93
102
|
end
|
94
103
|
if same
|
95
104
|
Kernel.puts "The path '#{path}' is used to backup " \
|
96
|
-
"the account '#{same
|
105
|
+
"the account '#{same.username}'"
|
97
106
|
false
|
98
107
|
else
|
99
108
|
true
|
@@ -102,11 +111,10 @@ module Imap::Backup
|
|
102
111
|
|
103
112
|
def modify_backup_path(menu)
|
104
113
|
menu.choice("modify backup path") do
|
105
|
-
existing = account
|
106
|
-
account
|
107
|
-
account
|
114
|
+
existing = account.local_path.clone
|
115
|
+
account.local_path = Configuration::Asker.backup_path(
|
116
|
+
account.local_path, ->(path) { path_modification_validator(path) }
|
108
117
|
)
|
109
|
-
account[:modified] = true if existing != account[:local_path]
|
110
118
|
end
|
111
119
|
end
|
112
120
|
|
@@ -127,21 +135,21 @@ module Imap::Backup
|
|
127
135
|
def delete_account(menu)
|
128
136
|
menu.choice("delete") do
|
129
137
|
if highline.agree("Are you sure? (y/n) ")
|
130
|
-
account
|
138
|
+
account.mark_for_deletion!
|
131
139
|
throw :done
|
132
140
|
end
|
133
141
|
end
|
134
142
|
end
|
135
143
|
|
136
144
|
def folders
|
137
|
-
account
|
145
|
+
account.folders || []
|
138
146
|
end
|
139
147
|
|
140
148
|
def masked_password
|
141
|
-
if (account
|
149
|
+
if (account.password == "") || account.password.nil?
|
142
150
|
"(unset)"
|
143
151
|
else
|
144
|
-
account
|
152
|
+
account.password.gsub(/./, "x")
|
145
153
|
end
|
146
154
|
end
|
147
155
|
|
@@ -53,7 +53,7 @@ module Imap::Backup
|
|
53
53
|
end
|
54
54
|
|
55
55
|
def selected?(folder_name)
|
56
|
-
config_folders = account
|
56
|
+
config_folders = account.folders
|
57
57
|
return false if config_folders.nil?
|
58
58
|
|
59
59
|
config_folders.find { |f| f[:name] == folder_name }
|
@@ -62,7 +62,7 @@ module Imap::Backup
|
|
62
62
|
def remove_missing
|
63
63
|
removed = []
|
64
64
|
config_folders = []
|
65
|
-
account
|
65
|
+
account.folders.each do |f|
|
66
66
|
found = imap_folders.find { |folder| folder == f[:name] }
|
67
67
|
if found
|
68
68
|
config_folders << f
|
@@ -73,8 +73,7 @@ module Imap::Backup
|
|
73
73
|
|
74
74
|
return if removed.empty?
|
75
75
|
|
76
|
-
account
|
77
|
-
account[:modified] = true
|
76
|
+
account.folders = config_folders
|
78
77
|
|
79
78
|
Kernel.puts <<~MESSAGE
|
80
79
|
The following folders have been removed: #{removed.join(', ')}
|
@@ -85,12 +84,11 @@ module Imap::Backup
|
|
85
84
|
|
86
85
|
def toggle_selection(folder_name)
|
87
86
|
if selected?(folder_name)
|
88
|
-
|
89
|
-
account
|
87
|
+
new_list = account.folders.select { |f| f[:name] != folder_name }
|
88
|
+
account.folders = new_list
|
90
89
|
else
|
91
|
-
account
|
92
|
-
account
|
93
|
-
account[:modified] = true
|
90
|
+
existing = account.folders || []
|
91
|
+
account.folders = existing + [{name: folder_name}]
|
94
92
|
end
|
95
93
|
end
|
96
94
|
|
@@ -1,5 +1,7 @@
|
|
1
1
|
require "highline"
|
2
2
|
|
3
|
+
require "imap/backup/account"
|
4
|
+
|
3
5
|
module Imap::Backup
|
4
6
|
module Configuration; end
|
5
7
|
|
@@ -39,12 +41,12 @@ module Imap::Backup
|
|
39
41
|
|
40
42
|
def account_items(menu)
|
41
43
|
config.accounts.each do |account|
|
42
|
-
next if account
|
44
|
+
next if account.marked_for_deletion?
|
43
45
|
|
44
|
-
item = account
|
45
|
-
item << " *" if account
|
46
|
+
item = account.username.clone
|
47
|
+
item << " *" if account.modified?
|
46
48
|
menu.choice(item) do
|
47
|
-
edit_account account
|
49
|
+
edit_account account.username
|
48
50
|
end
|
49
51
|
end
|
50
52
|
end
|
@@ -70,19 +72,19 @@ module Imap::Backup
|
|
70
72
|
end
|
71
73
|
|
72
74
|
def default_account_config(username)
|
73
|
-
|
75
|
+
::Imap::Backup::Account.new(
|
74
76
|
username: username,
|
75
77
|
password: "",
|
76
78
|
local_path: File.join(config.path, username.tr("@", "_")),
|
77
79
|
folders: []
|
78
|
-
|
80
|
+
).tap do |a|
|
79
81
|
server = Email::Provider.for_address(username)
|
80
|
-
|
82
|
+
a.server = server.host if server.host
|
81
83
|
end
|
82
84
|
end
|
83
85
|
|
84
86
|
def edit_account(username)
|
85
|
-
account = config.accounts.find { |a| a
|
87
|
+
account = config.accounts.find { |a| a.username == username }
|
86
88
|
if account.nil?
|
87
89
|
account = default_account_config(username)
|
88
90
|
config.accounts << account
|
@@ -1,11 +1,14 @@
|
|
1
1
|
require "json"
|
2
2
|
require "os"
|
3
3
|
|
4
|
+
require "imap/backup/account"
|
5
|
+
|
4
6
|
module Imap::Backup
|
5
7
|
module Configuration; end
|
6
8
|
|
7
9
|
class Configuration::Store
|
8
10
|
CONFIGURATION_DIRECTORY = File.expand_path("~/.imap-backup")
|
11
|
+
VERSION = "2.0"
|
9
12
|
|
10
13
|
attr_reader :pathname
|
11
14
|
|
@@ -19,6 +22,7 @@ module Imap::Backup
|
|
19
22
|
|
20
23
|
def initialize(pathname = self.class.default_pathname)
|
21
24
|
@pathname = pathname
|
25
|
+
@debug = nil
|
22
26
|
end
|
23
27
|
|
24
28
|
def path
|
@@ -26,53 +30,71 @@ module Imap::Backup
|
|
26
30
|
end
|
27
31
|
|
28
32
|
def save
|
33
|
+
ensure_loaded!
|
29
34
|
FileUtils.mkdir(path) if !File.directory?(path)
|
30
35
|
make_private(path) if !windows?
|
31
36
|
remove_modified_flags
|
32
37
|
remove_deleted_accounts
|
33
|
-
|
38
|
+
save_data = {
|
39
|
+
version: VERSION,
|
40
|
+
accounts: accounts.map(&:to_h),
|
41
|
+
debug: debug?
|
42
|
+
}
|
43
|
+
File.open(pathname, "w") { |f| f.write(JSON.pretty_generate(save_data)) }
|
34
44
|
FileUtils.chmod(0o600, pathname) if !windows?
|
35
45
|
end
|
36
46
|
|
37
47
|
def accounts
|
38
|
-
|
48
|
+
@accounts ||= begin
|
49
|
+
ensure_loaded!
|
50
|
+
data[:accounts].map { |data| Account.new(data) }
|
51
|
+
end
|
39
52
|
end
|
40
53
|
|
41
54
|
def modified?
|
42
|
-
|
55
|
+
ensure_loaded!
|
56
|
+
accounts.any? { |a| a.modified? || a.marked_for_deletion? }
|
43
57
|
end
|
44
58
|
|
45
59
|
def debug?
|
46
|
-
|
60
|
+
ensure_loaded!
|
61
|
+
@debug
|
47
62
|
end
|
48
63
|
|
49
64
|
def debug=(value)
|
50
|
-
|
65
|
+
ensure_loaded!
|
66
|
+
@debug = [true, false].include?(value) ? value : false
|
51
67
|
end
|
52
68
|
|
53
69
|
private
|
54
70
|
|
71
|
+
def ensure_loaded!
|
72
|
+
return true if @data
|
73
|
+
|
74
|
+
data
|
75
|
+
@debug = data.key?(:debug) ? data[:debug] == true : false
|
76
|
+
true
|
77
|
+
end
|
78
|
+
|
55
79
|
def data
|
56
80
|
@data ||=
|
57
81
|
begin
|
58
82
|
if File.exist?(pathname)
|
59
83
|
Utils.check_permissions(pathname, 0o600) if !windows?
|
60
84
|
contents = File.read(pathname)
|
61
|
-
|
85
|
+
JSON.parse(contents, symbolize_names: true)
|
62
86
|
else
|
63
|
-
|
87
|
+
{accounts: []}
|
64
88
|
end
|
65
|
-
data[:debug] = data.key?(:debug) ? data[:debug] == true : false
|
66
|
-
data
|
67
89
|
end
|
68
90
|
end
|
69
91
|
|
70
92
|
def remove_modified_flags
|
71
|
-
accounts.each { |a| a.
|
93
|
+
accounts.each { |a| a.clear_changes! }
|
72
94
|
end
|
73
95
|
|
74
96
|
def remove_deleted_accounts
|
75
|
-
accounts.reject! { |a| a
|
97
|
+
accounts.reject! { |a| a.marked_for_deletion? }
|
76
98
|
end
|
77
99
|
|
78
100
|
def make_private(path)
|
data/lib/imap/backup/version.rb
CHANGED
@@ -2,11 +2,13 @@ shared_context "imap-backup connection" do
|
|
2
2
|
let(:local_backup_path) { Dir.mktmpdir(nil, "tmp") }
|
3
3
|
let(:default_connection) { fixture("connection") }
|
4
4
|
let(:backup_folders) { nil }
|
5
|
-
let(:
|
6
|
-
|
7
|
-
|
8
|
-
|
5
|
+
let(:account) do
|
6
|
+
Imap::Backup::Account.new(
|
7
|
+
default_connection.merge(
|
8
|
+
local_path: local_backup_path,
|
9
|
+
folders: backup_folders
|
10
|
+
)
|
9
11
|
)
|
10
12
|
end
|
11
|
-
let(:connection) { Imap::Backup::Account::Connection.new(
|
13
|
+
let(:connection) { Imap::Backup::Account::Connection.new(account) }
|
12
14
|
end
|
@@ -17,10 +17,10 @@ describe Email::Provider do
|
|
17
17
|
end
|
18
18
|
|
19
19
|
context "with unknown providers" do
|
20
|
-
it "returns
|
20
|
+
it "returns the Unknown provider" do
|
21
21
|
result = described_class.for_address("foo@unknown.com")
|
22
22
|
|
23
|
-
expect(result).to be_a(Email::Provider::
|
23
|
+
expect(result).to be_a(Email::Provider::Unknown)
|
24
24
|
end
|
25
25
|
end
|
26
26
|
end
|
@@ -12,7 +12,7 @@ describe Imap::Backup::Account::Connection do
|
|
12
12
|
SERVER = "imap.example.com".freeze
|
13
13
|
USERNAME = "username@example.com".freeze
|
14
14
|
|
15
|
-
subject { described_class.new(
|
15
|
+
subject { described_class.new(account) }
|
16
16
|
|
17
17
|
let(:client) do
|
18
18
|
instance_double(
|
@@ -20,14 +20,16 @@ describe Imap::Backup::Account::Connection do
|
|
20
20
|
)
|
21
21
|
end
|
22
22
|
let(:imap_folders) { [] }
|
23
|
-
let(:
|
24
|
-
|
23
|
+
let(:account) do
|
24
|
+
instance_double(
|
25
|
+
Imap::Backup::Account,
|
25
26
|
username: USERNAME,
|
26
27
|
password: PASSWORD,
|
27
28
|
local_path: LOCAL_PATH,
|
28
29
|
folders: config_folders,
|
29
|
-
server: server
|
30
|
-
|
30
|
+
server: server,
|
31
|
+
connection_options: nil
|
32
|
+
)
|
31
33
|
end
|
32
34
|
let(:config_folders) { [FOLDER_CONFIG] }
|
33
35
|
let(:root_info) do
|
@@ -59,21 +61,10 @@ describe Imap::Backup::Account::Connection do
|
|
59
61
|
end
|
60
62
|
|
61
63
|
describe "#initialize" do
|
62
|
-
[
|
63
|
-
[:username, USERNAME],
|
64
|
-
[:password, PASSWORD],
|
65
|
-
[:local_path, LOCAL_PATH],
|
66
|
-
[:server, SERVER]
|
67
|
-
].each do |attr, expected|
|
68
|
-
it "expects #{attr}" do
|
69
|
-
expect(subject.public_send(attr)).to eq(expected)
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
64
|
it "creates the path" do
|
74
65
|
expect(Imap::Backup::Utils).to receive(:make_folder)
|
75
66
|
|
76
|
-
subject
|
67
|
+
subject
|
77
68
|
end
|
78
69
|
end
|
79
70
|
|
@@ -1,8 +1,15 @@
|
|
1
1
|
describe Imap::Backup::CLI::Local do
|
2
2
|
let(:list) do
|
3
|
-
instance_double(Imap::Backup::Configuration::List, accounts:
|
3
|
+
instance_double(Imap::Backup::Configuration::List, accounts: [account])
|
4
|
+
end
|
5
|
+
let(:account) do
|
6
|
+
instance_double(
|
7
|
+
Imap::Backup::Account,
|
8
|
+
username: email,
|
9
|
+
marked_for_deletion?: false,
|
10
|
+
modified?: false
|
11
|
+
)
|
4
12
|
end
|
5
|
-
let(:accounts) { [{username: email}] }
|
6
13
|
let(:connection) do
|
7
14
|
instance_double(
|
8
15
|
Imap::Backup::Account::Connection,
|
@@ -1,50 +1,52 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
1
|
+
module Imap::Backup
|
2
|
+
describe CLI::Utils do
|
3
|
+
let(:list) do
|
4
|
+
instance_double(Configuration::List, accounts: [account])
|
5
|
+
end
|
6
|
+
let(:account) { instance_double(Account, username: email) }
|
7
|
+
let(:connection) do
|
8
|
+
instance_double(
|
9
|
+
Account::Connection,
|
10
|
+
local_folders: local_folders
|
11
|
+
)
|
12
|
+
end
|
13
|
+
let(:local_folders) { [[serializer, folder]] }
|
14
|
+
let(:folder) do
|
15
|
+
instance_double(
|
16
|
+
Account::Folder,
|
17
|
+
exist?: true,
|
18
|
+
name: "name",
|
19
|
+
uid_validity: "uid_validity",
|
20
|
+
uids: %w(123 456)
|
21
|
+
)
|
22
|
+
end
|
23
|
+
let(:serializer) do
|
24
|
+
instance_double(
|
25
|
+
Serializer::Mbox,
|
26
|
+
uids: %w(123 789),
|
27
|
+
apply_uid_validity: nil,
|
28
|
+
save: nil
|
29
|
+
)
|
30
|
+
end
|
31
|
+
let(:email) { "foo@example.com" }
|
31
32
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
33
|
+
before do
|
34
|
+
allow(Configuration::List).to receive(:new) { list }
|
35
|
+
allow(Account::Connection).to receive(:new) { connection }
|
36
|
+
end
|
36
37
|
|
37
|
-
|
38
|
-
|
39
|
-
|
38
|
+
describe "ignore_history" do
|
39
|
+
it "ensures the local UID validity matches the server" do
|
40
|
+
subject.ignore_history(email)
|
40
41
|
|
41
|
-
|
42
|
-
|
42
|
+
expect(serializer).to have_received(:apply_uid_validity).with("uid_validity")
|
43
|
+
end
|
43
44
|
|
44
|
-
|
45
|
-
|
45
|
+
it "fills the local folder with fake emails" do
|
46
|
+
subject.ignore_history(email)
|
46
47
|
|
47
|
-
|
48
|
+
expect(serializer).to have_received(:save).with("456", /From: fake@email.com/)
|
49
|
+
end
|
48
50
|
end
|
49
51
|
end
|
50
52
|
end
|
@@ -6,7 +6,32 @@ describe Imap::Backup::Configuration::Account do
|
|
6
6
|
|
7
7
|
subject { described_class.new(store, account, highline) }
|
8
8
|
|
9
|
-
let(:account)
|
9
|
+
let(:account) do
|
10
|
+
instance_double(
|
11
|
+
Imap::Backup::Account,
|
12
|
+
username: existing_email,
|
13
|
+
password: existing_password,
|
14
|
+
server: current_server,
|
15
|
+
connection_options: nil,
|
16
|
+
local_path: "/backup/path",
|
17
|
+
folders: [{name: "my_folder"}]
|
18
|
+
)
|
19
|
+
end
|
20
|
+
let(:account1) do
|
21
|
+
instance_double(
|
22
|
+
Imap::Backup::Account,
|
23
|
+
username: other_email,
|
24
|
+
local_path: other_existing_path
|
25
|
+
)
|
26
|
+
end
|
27
|
+
let(:accounts) { [account, account1] }
|
28
|
+
let(:existing_email) { "user@example.com" }
|
29
|
+
let(:new_email) { "foo@example.com" }
|
30
|
+
let(:current_server) { "imap.example.com" }
|
31
|
+
let(:existing_password) { "password" }
|
32
|
+
let(:other_email) { "other@example.com" }
|
33
|
+
let(:other_existing_path) { "/other/existing/path" }
|
34
|
+
|
10
35
|
let(:highline) { HIGHLINE }
|
11
36
|
let(:store) { STORE }
|
12
37
|
|
@@ -43,28 +68,6 @@ describe Imap::Backup::Configuration::Account do
|
|
43
68
|
let(:store) do
|
44
69
|
instance_double(Imap::Backup::Configuration::Store, accounts: accounts)
|
45
70
|
end
|
46
|
-
let(:accounts) { [account, account1] }
|
47
|
-
let(:account) do
|
48
|
-
{
|
49
|
-
username: existing_email,
|
50
|
-
server: current_server,
|
51
|
-
local_path: "/backup/path",
|
52
|
-
folders: [{name: "my_folder"}],
|
53
|
-
password: existing_password
|
54
|
-
}
|
55
|
-
end
|
56
|
-
let(:account1) do
|
57
|
-
{
|
58
|
-
username: other_email,
|
59
|
-
local_path: other_existing_path
|
60
|
-
}
|
61
|
-
end
|
62
|
-
let(:existing_email) { "user@example.com" }
|
63
|
-
let(:new_email) { "foo@example.com" }
|
64
|
-
let(:current_server) { "imap.example.com" }
|
65
|
-
let(:existing_password) { "password" }
|
66
|
-
let(:other_email) { "other@example.com" }
|
67
|
-
let(:other_existing_path) { "/other/existing/path" }
|
68
71
|
|
69
72
|
before do
|
70
73
|
allow(Kernel).to receive(:system)
|
@@ -139,6 +142,8 @@ describe Imap::Backup::Configuration::Account do
|
|
139
142
|
|
140
143
|
describe "choosing 'modify email'" do
|
141
144
|
before do
|
145
|
+
allow(account).to receive(:"username=")
|
146
|
+
allow(account).to receive(:"server=")
|
142
147
|
allow(Imap::Backup::Configuration::Asker).
|
143
148
|
to receive(:email) { new_email }
|
144
149
|
subject.run
|
@@ -158,7 +163,7 @@ describe Imap::Backup::Configuration::Account do
|
|
158
163
|
let(:current_server) { nil }
|
159
164
|
|
160
165
|
it "sets a default server" do
|
161
|
-
expect(account
|
166
|
+
expect(account).to have_received(:"server=").with(expected)
|
162
167
|
end
|
163
168
|
end
|
164
169
|
|
@@ -166,7 +171,7 @@ describe Imap::Backup::Configuration::Account do
|
|
166
171
|
let(:current_server) { "" }
|
167
172
|
|
168
173
|
it "sets a default server" do
|
169
|
-
expect(account
|
174
|
+
expect(account).to have_received(:"server=").with(expected)
|
170
175
|
end
|
171
176
|
end
|
172
177
|
end
|
@@ -183,17 +188,15 @@ describe Imap::Backup::Configuration::Account do
|
|
183
188
|
end
|
184
189
|
|
185
190
|
it "does not set a default server" do
|
186
|
-
expect(account
|
191
|
+
expect(account).to_not have_received(:"server=")
|
187
192
|
end
|
188
193
|
end
|
189
194
|
end
|
190
195
|
|
191
196
|
context "when the email is new" do
|
192
197
|
it "modifies the email address" do
|
193
|
-
expect(account
|
198
|
+
expect(account).to have_received(:"username=").with(new_email)
|
194
199
|
end
|
195
|
-
|
196
|
-
include_examples "it flags the account as modified"
|
197
200
|
end
|
198
201
|
|
199
202
|
context "when the email already exists" do
|
@@ -205,10 +208,8 @@ describe Imap::Backup::Configuration::Account do
|
|
205
208
|
end
|
206
209
|
|
207
210
|
it "doesn't set the email" do
|
208
|
-
expect(account
|
211
|
+
expect(account.username).to eq(existing_email)
|
209
212
|
end
|
210
|
-
|
211
|
-
include_examples "it doesn't flag the account as modified"
|
212
213
|
end
|
213
214
|
end
|
214
215
|
|
@@ -216,6 +217,7 @@ describe Imap::Backup::Configuration::Account do
|
|
216
217
|
let(:new_password) { "new_password" }
|
217
218
|
|
218
219
|
before do
|
220
|
+
allow(account).to receive(:"password=")
|
219
221
|
allow(Imap::Backup::Configuration::Asker).
|
220
222
|
to receive(:password) { new_password }
|
221
223
|
subject.run
|
@@ -224,20 +226,16 @@ describe Imap::Backup::Configuration::Account do
|
|
224
226
|
|
225
227
|
context "when the user enters a password" do
|
226
228
|
it "updates the password" do
|
227
|
-
expect(account
|
229
|
+
expect(account).to have_received(:"password=").with(new_password)
|
228
230
|
end
|
229
|
-
|
230
|
-
include_examples "it flags the account as modified"
|
231
231
|
end
|
232
232
|
|
233
233
|
context "when the user cancels" do
|
234
234
|
let(:new_password) { nil }
|
235
235
|
|
236
236
|
it "does nothing" do
|
237
|
-
expect(account
|
237
|
+
expect(account.password).to eq(existing_password)
|
238
238
|
end
|
239
|
-
|
240
|
-
include_examples "it doesn't flag the account as modified"
|
241
239
|
end
|
242
240
|
end
|
243
241
|
|
@@ -245,6 +243,7 @@ describe Imap::Backup::Configuration::Account do
|
|
245
243
|
let(:server) { "server" }
|
246
244
|
|
247
245
|
before do
|
246
|
+
allow(account).to receive(:"server=")
|
248
247
|
allow(highline).to receive(:ask).with("server: ") { server }
|
249
248
|
|
250
249
|
subject.run
|
@@ -253,16 +252,15 @@ describe Imap::Backup::Configuration::Account do
|
|
253
252
|
end
|
254
253
|
|
255
254
|
it "updates the server" do
|
256
|
-
expect(account
|
255
|
+
expect(account).to have_received(:"server=").with(server)
|
257
256
|
end
|
258
|
-
|
259
|
-
include_examples "it flags the account as modified"
|
260
257
|
end
|
261
258
|
|
262
259
|
describe "choosing 'modify backup path'" do
|
263
260
|
let(:new_backup_path) { "/new/path" }
|
264
261
|
|
265
262
|
before do
|
263
|
+
allow(account).to receive(:"local_path=")
|
266
264
|
@validator = nil
|
267
265
|
allow(
|
268
266
|
Imap::Backup::Configuration::Asker
|
@@ -275,7 +273,7 @@ describe Imap::Backup::Configuration::Account do
|
|
275
273
|
end
|
276
274
|
|
277
275
|
it "updates the path" do
|
278
|
-
expect(account
|
276
|
+
expect(account).to have_received(:"local_path=").with(new_backup_path)
|
279
277
|
end
|
280
278
|
|
281
279
|
context "when the path is not used by other backups" do
|
@@ -293,8 +291,6 @@ describe Imap::Backup::Configuration::Account do
|
|
293
291
|
# rubocop:enable RSpec/InstanceVariable
|
294
292
|
end
|
295
293
|
end
|
296
|
-
|
297
|
-
include_examples "it flags the account as modified"
|
298
294
|
end
|
299
295
|
|
300
296
|
describe "choosing 'choose backup folders'" do
|
@@ -333,6 +329,7 @@ describe Imap::Backup::Configuration::Account do
|
|
333
329
|
let(:confirmed) { true }
|
334
330
|
|
335
331
|
before do
|
332
|
+
allow(account).to receive(:mark_for_deletion!)
|
336
333
|
allow(highline).to receive(:agree) { confirmed }
|
337
334
|
subject.run
|
338
335
|
catch :done do
|
@@ -345,13 +342,17 @@ describe Imap::Backup::Configuration::Account do
|
|
345
342
|
end
|
346
343
|
|
347
344
|
context "when the user confirms deletion" do
|
348
|
-
|
345
|
+
it "flags the account to be deleted" do
|
346
|
+
expect(account).to have_received(:mark_for_deletion!)
|
347
|
+
end
|
349
348
|
end
|
350
349
|
|
351
350
|
context "without confirmation" do
|
352
351
|
let(:confirmed) { false }
|
353
352
|
|
354
|
-
|
353
|
+
it "doesn't flag the account to be deleted" do
|
354
|
+
expect(account).to_not have_received(:mark_for_deletion!)
|
355
|
+
end
|
355
356
|
end
|
356
357
|
end
|
357
358
|
end
|
@@ -9,7 +9,14 @@ describe Imap::Backup::Configuration::FolderChooser do
|
|
9
9
|
Imap::Backup::Account::Connection, folders: connection_folders
|
10
10
|
)
|
11
11
|
end
|
12
|
-
let(:account)
|
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) { [] }
|
13
20
|
let(:connection_folders) { [] }
|
14
21
|
let!(:highline_streams) { prepare_highline }
|
15
22
|
let(:input) { highline_streams[0] }
|
@@ -36,7 +43,7 @@ describe Imap::Backup::Configuration::FolderChooser do
|
|
36
43
|
end
|
37
44
|
|
38
45
|
describe "folder listing" do
|
39
|
-
let(:
|
46
|
+
let(:account_folders) { [{name: "my_folder"}]}
|
40
47
|
let(:connection_folders) do
|
41
48
|
# N.B. my_folder is already backed up
|
42
49
|
%w(my_folder another_folder)
|
@@ -62,10 +69,9 @@ describe Imap::Backup::Configuration::FolderChooser do
|
|
62
69
|
end
|
63
70
|
|
64
71
|
specify "are added to the account" do
|
65
|
-
expect(account
|
72
|
+
expect(account).to have_received(:"folders=").
|
73
|
+
with([{name: "my_folder"}, {name: "another_folder"}])
|
66
74
|
end
|
67
|
-
|
68
|
-
include_examples "it flags the account as modified"
|
69
75
|
end
|
70
76
|
|
71
77
|
context "when removing folders" do
|
@@ -76,22 +82,16 @@ describe Imap::Backup::Configuration::FolderChooser do
|
|
76
82
|
end
|
77
83
|
|
78
84
|
specify "are removed from the account" do
|
79
|
-
expect(account
|
85
|
+
expect(account).to have_received(:"folders=").with([])
|
80
86
|
end
|
81
|
-
|
82
|
-
include_examples "it flags the account as modified"
|
83
87
|
end
|
84
88
|
end
|
85
89
|
|
86
90
|
context "with missing remote folders" do
|
87
|
-
let(:
|
88
|
-
|
89
|
-
end
|
90
|
-
let(:connection_folders) do
|
91
|
-
[
|
92
|
-
instance_double(Imap::Backup::Account::Folder, name: "on_server")
|
93
|
-
]
|
91
|
+
let(:account_folders) do
|
92
|
+
[{name: "on_server"}, {name: "not_on_server"}]
|
94
93
|
end
|
94
|
+
let(:connection_folders) { ["on_server"] }
|
95
95
|
|
96
96
|
before do
|
97
97
|
allow(Kernel).to receive(:puts)
|
@@ -99,10 +99,9 @@ describe Imap::Backup::Configuration::FolderChooser do
|
|
99
99
|
end
|
100
100
|
|
101
101
|
specify "are removed from the account" do
|
102
|
-
expect(account
|
102
|
+
expect(account).to have_received(:"folders=").
|
103
|
+
with([{name: "on_server"}])
|
103
104
|
end
|
104
|
-
|
105
|
-
include_examples "it flags the account as modified"
|
106
105
|
end
|
107
106
|
|
108
107
|
context "when folders are not available" do
|
@@ -3,8 +3,31 @@ describe Imap::Backup::Configuration::Setup do
|
|
3
3
|
|
4
4
|
subject { described_class.new }
|
5
5
|
|
6
|
-
let(:
|
7
|
-
|
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] }
|
8
31
|
let(:store) do
|
9
32
|
instance_double(
|
10
33
|
Imap::Backup::Configuration::Store,
|
@@ -63,9 +86,7 @@ describe Imap::Backup::Configuration::Setup do
|
|
63
86
|
end
|
64
87
|
|
65
88
|
describe "listing" do
|
66
|
-
let(:accounts) { [
|
67
|
-
let(:modified) { {username: "modified@example.com", modified: true} }
|
68
|
-
let(:deleted) { {username: "deleted@example.com", delete: true} }
|
89
|
+
let(:accounts) { [normal_account, modified_account, deleted_account] }
|
69
90
|
|
70
91
|
before { subject.run }
|
71
92
|
|
@@ -98,7 +119,7 @@ describe Imap::Backup::Configuration::Setup do
|
|
98
119
|
allow(Imap::Backup::Configuration::Asker).to receive(:email).
|
99
120
|
with(no_args) { "new@example.com" }
|
100
121
|
allow(Imap::Backup::Configuration::Account).to receive(:new).
|
101
|
-
with(store,
|
122
|
+
with(store, normal_account, anything) { account }
|
102
123
|
end
|
103
124
|
|
104
125
|
it "edits the account" do
|
@@ -134,19 +155,19 @@ describe Imap::Backup::Configuration::Setup do
|
|
134
155
|
end
|
135
156
|
|
136
157
|
it "sets username" do
|
137
|
-
expect(accounts[1]
|
158
|
+
expect(accounts[1].username).to eq(added_email)
|
138
159
|
end
|
139
160
|
|
140
161
|
it "sets blank password" do
|
141
|
-
expect(accounts[1]
|
162
|
+
expect(accounts[1].password).to eq("")
|
142
163
|
end
|
143
164
|
|
144
165
|
it "sets local_path" do
|
145
|
-
expect(accounts[1]
|
166
|
+
expect(accounts[1].local_path).to eq(local_path)
|
146
167
|
end
|
147
168
|
|
148
169
|
it "sets folders" do
|
149
|
-
expect(accounts[1]
|
170
|
+
expect(accounts[1].folders).to eq([])
|
150
171
|
end
|
151
172
|
|
152
173
|
context "when the account is a GMail account" do
|
@@ -154,12 +175,12 @@ describe Imap::Backup::Configuration::Setup do
|
|
154
175
|
let(:local_path) { "/base/path/new_gmail.com" }
|
155
176
|
|
156
177
|
it "sets the server" do
|
157
|
-
expect(accounts[1]
|
178
|
+
expect(accounts[1].server).to eq(gmail_imap_server)
|
158
179
|
end
|
159
180
|
end
|
160
181
|
|
161
182
|
it "doesn't flag the unedited account as modified" do
|
162
|
-
expect(accounts[1]
|
183
|
+
expect(accounts[1].modified?).to be_falsey
|
163
184
|
end
|
164
185
|
end
|
165
186
|
|
@@ -8,10 +8,12 @@ describe Imap::Backup::Configuration::Store do
|
|
8
8
|
let(:file_path) { File.join(directory, "/config.json") }
|
9
9
|
let(:file_exists) { true }
|
10
10
|
let(:directory_exists) { true }
|
11
|
-
let(:data) { {debug: debug, accounts: accounts} }
|
12
11
|
let(:debug) { true }
|
13
|
-
let(:accounts) { [] }
|
14
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"}) }
|
15
17
|
|
16
18
|
before do
|
17
19
|
stub_const(
|
@@ -48,8 +50,8 @@ describe Imap::Backup::Configuration::Store do
|
|
48
50
|
end
|
49
51
|
|
50
52
|
describe "#modified?" do
|
51
|
-
context "with accounts
|
52
|
-
|
53
|
+
context "with modified accounts" do
|
54
|
+
before { subject.accounts[0].username = "changed" }
|
53
55
|
|
54
56
|
it "is true" do
|
55
57
|
expect(subject.modified?).to be_truthy
|
@@ -57,7 +59,7 @@ describe Imap::Backup::Configuration::Store do
|
|
57
59
|
end
|
58
60
|
|
59
61
|
context "with accounts flagged 'delete'" do
|
60
|
-
|
62
|
+
before { subject.accounts[0].mark_for_deletion! }
|
61
63
|
|
62
64
|
it "is true" do
|
63
65
|
expect(subject.modified?).to be_truthy
|
@@ -65,8 +67,6 @@ describe Imap::Backup::Configuration::Store do
|
|
65
67
|
end
|
66
68
|
|
67
69
|
context "without accounts flagged 'modified'" do
|
68
|
-
let(:accounts) { [{name: "foo"}] }
|
69
|
-
|
70
70
|
it "is false" do
|
71
71
|
expect(subject.modified?).to be_falsey
|
72
72
|
end
|
@@ -156,19 +156,14 @@ describe Imap::Backup::Configuration::Store do
|
|
156
156
|
subject.save
|
157
157
|
end
|
158
158
|
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
before { subject.save }
|
163
|
-
|
164
|
-
it "skips the 'modified' flag" do
|
165
|
-
expected = Marshal.load(Marshal.dump(data))
|
166
|
-
expected[:accounts][0].delete(:modified)
|
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" }
|
167
162
|
|
168
|
-
|
163
|
+
expect(JSON).to receive(:pretty_generate).
|
164
|
+
with(hash_including({accounts: ["Account1", "Account2"]}))
|
169
165
|
|
170
|
-
|
171
|
-
end
|
166
|
+
subject.save
|
172
167
|
end
|
173
168
|
|
174
169
|
context "when accounts are to be deleted" do
|
@@ -179,11 +174,15 @@ describe Imap::Backup::Configuration::Store do
|
|
179
174
|
]
|
180
175
|
end
|
181
176
|
|
182
|
-
|
183
|
-
|
184
|
-
|
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
|
185
182
|
|
186
|
-
|
183
|
+
it "does not save them" do
|
184
|
+
expect(JSON).to receive(:pretty_generate).
|
185
|
+
with(hash_including({accounts: ["Account2"]}))
|
187
186
|
|
188
187
|
subject.save
|
189
188
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: imap-backup
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.0.
|
4
|
+
version: 4.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joe Yates
|
@@ -237,7 +237,6 @@ files:
|
|
237
237
|
- spec/spec_helper.rb
|
238
238
|
- spec/support/fixtures.rb
|
239
239
|
- spec/support/higline_test_helpers.rb
|
240
|
-
- spec/support/shared_examples/account_flagging.rb
|
241
240
|
- spec/support/silence_logging.rb
|
242
241
|
- spec/unit/email/mboxrd/message_spec.rb
|
243
242
|
- spec/unit/email/provider/apple_mail_spec.rb
|
@@ -316,7 +315,6 @@ test_files:
|
|
316
315
|
- spec/unit/imap/backup/serializer/mbox_enumerator_spec.rb
|
317
316
|
- spec/unit/imap/backup/uploader_spec.rb
|
318
317
|
- spec/support/fixtures.rb
|
319
|
-
- spec/support/shared_examples/account_flagging.rb
|
320
318
|
- spec/support/higline_test_helpers.rb
|
321
319
|
- spec/support/silence_logging.rb
|
322
320
|
- spec/gather_rspec_coverage.rb
|
@@ -1,23 +0,0 @@
|
|
1
|
-
shared_examples "it flags the account as modified" do
|
2
|
-
it "flags that the account has changed" do
|
3
|
-
expect(account[:modified]).to be_truthy
|
4
|
-
end
|
5
|
-
end
|
6
|
-
|
7
|
-
shared_examples "it doesn't flag the account as modified" do
|
8
|
-
it "does not flag that the account has changed" do
|
9
|
-
expect(account[:modified]).to be_falsey
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
shared_examples "it flags the account to be deleted" do
|
14
|
-
it "flags that the account is to be deleted" do
|
15
|
-
expect(account[:delete]).to be_truthy
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
shared_examples "it doesn't flag the account to be deleted" do
|
20
|
-
it "does not flags that the account is to be deleted" do
|
21
|
-
expect(account[:delete]).to be_falsey
|
22
|
-
end
|
23
|
-
end
|