imap-backup 4.0.5 → 4.0.6
Sign up to get free protection for your applications and to get access to all the features.
- 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
|