imap-backup 4.0.2 → 4.0.3
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/README.md +9 -1
- data/docs/development.md +1 -2
- data/imap-backup.gemspec +1 -0
- data/lib/email/provider/apple_mail.rb +7 -0
- data/lib/email/provider/default.rb +12 -0
- data/lib/email/provider/fastmail.rb +7 -0
- data/lib/email/provider/gmail.rb +7 -0
- data/lib/email/provider.rb +16 -26
- data/lib/imap/backup/account/connection.rb +19 -29
- data/lib/imap/backup/account/folder.rb +9 -10
- data/lib/imap/backup/cli/helpers.rb +1 -0
- data/lib/imap/backup/cli/local.rb +4 -1
- data/lib/imap/backup/cli/utils.rb +16 -5
- data/lib/imap/backup/client/apple_mail.rb +11 -0
- data/lib/imap/backup/client/default.rb +51 -0
- data/lib/imap/backup/configuration/account.rb +3 -1
- data/lib/imap/backup/configuration/connection_tester.rb +1 -1
- data/lib/imap/backup/configuration/store.rb +10 -5
- data/lib/imap/backup/downloader.rb +3 -4
- data/lib/imap/backup/thunderbird/mailbox_exporter.rb +12 -25
- data/lib/imap/backup/version.rb +1 -1
- data/lib/thunderbird/install.rb +16 -0
- data/lib/thunderbird/local_folder.rb +33 -65
- data/lib/thunderbird/profiles.rb +18 -10
- data/lib/thunderbird/subdirectory.rb +96 -0
- data/lib/thunderbird/{local_folder_placeholder.rb → subdirectory_placeholder.rb} +4 -4
- data/lib/thunderbird.rb +10 -2
- data/spec/features/restore_spec.rb +1 -1
- data/spec/features/support/email_server.rb +2 -2
- data/spec/unit/email/provider/apple_mail_spec.rb +7 -0
- data/spec/unit/email/provider/default_spec.rb +17 -0
- data/spec/unit/email/provider/fastmail_spec.rb +7 -0
- data/spec/unit/email/provider/gmail_spec.rb +7 -0
- data/spec/unit/email/provider_spec.rb +12 -25
- data/spec/unit/imap/backup/account/connection_spec.rb +26 -51
- data/spec/unit/imap/backup/account/folder_spec.rb +22 -22
- data/spec/unit/imap/backup/cli/utils_spec.rb +2 -2
- data/spec/unit/imap/backup/client/default_spec.rb +22 -0
- data/spec/unit/imap/backup/configuration/connection_tester_spec.rb +3 -3
- data/spec/unit/imap/backup/configuration/store_spec.rb +25 -12
- data/spec/unit/imap/backup/downloader_spec.rb +1 -2
- metadata +57 -26
- data/lib/thunderbird/mailbox.rb +0 -25
@@ -1,97 +1,65 @@
|
|
1
1
|
require "thunderbird/profile"
|
2
|
-
require "thunderbird/
|
2
|
+
require "thunderbird/subdirectory"
|
3
3
|
|
4
|
+
# A local folder is a file containing emails
|
4
5
|
class Thunderbird::LocalFolder
|
5
|
-
attr_reader :
|
6
|
+
attr_reader :path
|
6
7
|
attr_reader :profile
|
7
8
|
|
8
|
-
def initialize(profile,
|
9
|
+
def initialize(profile, path)
|
9
10
|
@profile = profile
|
10
|
-
@
|
11
|
+
@path = path
|
11
12
|
end
|
12
13
|
|
13
|
-
def
|
14
|
-
if
|
15
|
-
path = File.join(parent.full_path, folder_path_elements[-1])
|
16
|
-
Thunderbird::LocalFolderPlaceholder.new(path)
|
17
|
-
end
|
18
|
-
end
|
14
|
+
def set_up
|
15
|
+
return if path_elements.empty?
|
19
16
|
|
20
|
-
|
21
|
-
File.directory?(full_path)
|
22
|
-
end
|
17
|
+
return true if !in_subdirectory?
|
23
18
|
|
24
|
-
|
25
|
-
File.join(profile.local_folders_path, relative_path)
|
19
|
+
subdirectory.set_up
|
26
20
|
end
|
27
21
|
|
28
|
-
def
|
29
|
-
if
|
30
|
-
|
22
|
+
def full_path
|
23
|
+
if in_subdirectory?
|
24
|
+
File.join(subdirectory.full_path, folder_name)
|
25
|
+
else
|
26
|
+
folder_name
|
31
27
|
end
|
32
28
|
end
|
33
29
|
|
34
|
-
def
|
35
|
-
|
30
|
+
def exists?
|
31
|
+
File.exist?(full_path)
|
36
32
|
end
|
37
33
|
|
38
|
-
def
|
39
|
-
|
34
|
+
def msf_path
|
35
|
+
"#{path}.msf"
|
40
36
|
end
|
41
37
|
|
42
|
-
def
|
43
|
-
File.
|
38
|
+
def msf_exists?
|
39
|
+
File.exist?(msf_path)
|
44
40
|
end
|
45
41
|
|
46
|
-
|
47
|
-
folder_path_elements.map { |p| "#{p}.sbd" }
|
48
|
-
end
|
42
|
+
private
|
49
43
|
|
50
|
-
def
|
51
|
-
|
44
|
+
def in_subdirectory?
|
45
|
+
path_elements.count > 1
|
52
46
|
end
|
53
47
|
|
54
|
-
def
|
55
|
-
|
56
|
-
return if !ok
|
48
|
+
def subdirectory
|
49
|
+
return nil if !in_subdirectory?
|
57
50
|
|
58
|
-
|
51
|
+
Thunderbird::Subdirectory.new(profile, subdirectory_path)
|
59
52
|
end
|
60
53
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
return true if !parent
|
65
|
-
|
66
|
-
parent.ensure_initialized
|
67
|
-
|
68
|
-
local_folder_placeholder.ensure_initialized
|
54
|
+
def path_elements
|
55
|
+
path.split(File::SEPARATOR)
|
56
|
+
end
|
69
57
|
|
70
|
-
|
58
|
+
def subdirectory_path
|
59
|
+
File.join(path_elements[0..-2])
|
71
60
|
end
|
72
61
|
|
73
|
-
def
|
74
|
-
|
75
|
-
|
76
|
-
parent_ok = parent.check
|
77
|
-
|
78
|
-
return if !parent_ok
|
79
|
-
|
80
|
-
case
|
81
|
-
when local_folder_placeholder.exists? && !directory_exists?
|
82
|
-
Kernel.puts "Can't set up folder '#{folder_path}': '#{local_folder_placeholder.path}' exists, but '#{full_path}' is missing"
|
83
|
-
false
|
84
|
-
when directory_exists? && !local_folder_placeholder.exists?
|
85
|
-
Kernel.puts "Can't set up folder '#{folder_path}': '#{full_path}' exists, but '#{local_folder_placeholder.path}' is missing"
|
86
|
-
false
|
87
|
-
when local_folder_placeholder.exists? && !local_folder_placeholder.is_regular?
|
88
|
-
Kernel.puts "Can't set up folder '#{folder_path}': '#{local_folder_placeholder.path}' exists, but it is not a regular file"
|
89
|
-
false
|
90
|
-
when directory_exists? && !is_directory?
|
91
|
-
Kernel.puts "Can't set up folder '#{folder_path}': '#{full_path}' exists, but it is not a directory"
|
92
|
-
false
|
93
|
-
else
|
94
|
-
true
|
95
|
-
end
|
62
|
+
def folder_name
|
63
|
+
path_elements[-1]
|
96
64
|
end
|
97
65
|
end
|
data/lib/thunderbird/profiles.rb
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
require "thunderbird"
|
2
|
+
require "thunderbird/install"
|
2
3
|
require "thunderbird/profile"
|
3
4
|
|
4
5
|
# http://kb.mozillazine.org/Profiles.ini_file
|
5
6
|
class Thunderbird::Profiles
|
6
|
-
def
|
7
|
-
title, entries = blocks.find { |_name, entries| entries[:
|
7
|
+
def profile_for_path(path)
|
8
|
+
title, entries = blocks.find { |_name, entries| entries[:Path] == path }
|
8
9
|
|
9
10
|
Thunderbird::Profile.new(title, entries) if title
|
10
11
|
end
|
@@ -12,11 +13,16 @@ class Thunderbird::Profiles
|
|
12
13
|
def profile(name)
|
13
14
|
title, entries = blocks.find { |_name, entries| entries[:Name] == name }
|
14
15
|
|
15
|
-
return nil if !title
|
16
|
-
|
17
16
|
Thunderbird::Profile.new(title, entries) if title
|
18
17
|
end
|
19
18
|
|
19
|
+
def installs
|
20
|
+
@installs ||= begin
|
21
|
+
pairs = blocks.filter { |name, _entries| name.start_with?("Install") }
|
22
|
+
pairs.map { |title, entries| Thunderbird::Install.new(title, entries) }
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
20
26
|
private
|
21
27
|
|
22
28
|
# Parse profiles.ini.
|
@@ -31,7 +37,11 @@ class Thunderbird::Profiles
|
|
31
37
|
|
32
38
|
loop do
|
33
39
|
line = f.gets
|
34
|
-
|
40
|
+
if !line
|
41
|
+
blocks[title] = entries if title
|
42
|
+
break
|
43
|
+
end
|
44
|
+
|
35
45
|
line.chomp!
|
36
46
|
|
37
47
|
# Is this line the start of a new block
|
@@ -43,12 +53,10 @@ class Thunderbird::Profiles
|
|
43
53
|
# Start a new block
|
44
54
|
title = match[1]
|
45
55
|
entries = {}
|
46
|
-
|
56
|
+
elsif line != ""
|
47
57
|
# Collect entries until we get to the next title
|
48
|
-
|
49
|
-
|
50
|
-
entries[key.to_sym] = value
|
51
|
-
end
|
58
|
+
key, value = line.split("=")
|
59
|
+
entries[key.to_sym] = value
|
52
60
|
end
|
53
61
|
end
|
54
62
|
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
require "thunderbird/subdirectory_placeholder"
|
2
|
+
|
3
|
+
class Thunderbird::Subdirectory
|
4
|
+
# `path` is the UI path, it doesn't have the '.sbd' extensions
|
5
|
+
# that are present in the real, file system path
|
6
|
+
attr_reader :path
|
7
|
+
attr_reader :profile
|
8
|
+
|
9
|
+
def initialize(profile, path)
|
10
|
+
@profile = profile
|
11
|
+
@path = path
|
12
|
+
end
|
13
|
+
|
14
|
+
def set_up
|
15
|
+
raise "Cannot create a subdirectory without a path" if !sub_directory?
|
16
|
+
|
17
|
+
if sub_sub_directory?
|
18
|
+
parent_ok = parent.set_up
|
19
|
+
return false if !parent_ok
|
20
|
+
end
|
21
|
+
|
22
|
+
ok = check
|
23
|
+
return false if !ok
|
24
|
+
|
25
|
+
FileUtils.mkdir_p full_path
|
26
|
+
placeholder.touch
|
27
|
+
|
28
|
+
true
|
29
|
+
end
|
30
|
+
|
31
|
+
# subdirectory relative path is 'Foo.sbd/Bar.sbd/Baz.sbd'
|
32
|
+
def full_path
|
33
|
+
relative_path = File.join(subdirectories)
|
34
|
+
File.join(profile.local_folders_path, relative_path)
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def sub_directory?
|
40
|
+
path_elements.any?
|
41
|
+
end
|
42
|
+
|
43
|
+
def sub_sub_directory?
|
44
|
+
path_elements.count > 1
|
45
|
+
end
|
46
|
+
|
47
|
+
def parent
|
48
|
+
return nil if !sub_sub_directory?
|
49
|
+
|
50
|
+
self.class.new(profile, File.join(path_elements[0..-2]))
|
51
|
+
end
|
52
|
+
|
53
|
+
# placeholder relative path is 'Foo.sbd/Bar.sbd/Baz'
|
54
|
+
def placeholder
|
55
|
+
@placeholder = begin
|
56
|
+
relative_path = File.join(subdirectories[0..-2], path_elements[-1])
|
57
|
+
path = File.join(profile.local_folders_path, relative_path)
|
58
|
+
Thunderbird::SubdirectoryPlaceholder.new(path)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def path_elements
|
63
|
+
path.split(File::SEPARATOR)
|
64
|
+
end
|
65
|
+
|
66
|
+
def exists?
|
67
|
+
File.exist?(full_path)
|
68
|
+
end
|
69
|
+
|
70
|
+
def directory?
|
71
|
+
File.directory?(full_path)
|
72
|
+
end
|
73
|
+
|
74
|
+
def subdirectories
|
75
|
+
path_elements.map { |p| "#{p}.sbd" }
|
76
|
+
end
|
77
|
+
|
78
|
+
def check
|
79
|
+
case
|
80
|
+
when placeholder.exists? && !exists?
|
81
|
+
Kernel.puts "Can't set up folder '#{folder_path}': '#{placeholder.path}' exists, but '#{full_path}' is missing"
|
82
|
+
false
|
83
|
+
when exists? && !placeholder.exists?
|
84
|
+
Kernel.puts "Can't set up folder '#{folder_path}': '#{full_path}' exists, but '#{placeholder.path}' is missing"
|
85
|
+
false
|
86
|
+
when placeholder.exists? && !placeholder.regular?
|
87
|
+
Kernel.puts "Can't set up folder '#{folder_path}': '#{placeholder.path}' exists, but it is not a regular file"
|
88
|
+
false
|
89
|
+
when exists? && !directory?
|
90
|
+
Kernel.puts "Can't set up folder '#{folder_path}': '#{full_path}' exists, but it is not a directory"
|
91
|
+
false
|
92
|
+
else
|
93
|
+
true
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# Each subdirectory is "accompanied" by a blank
|
2
2
|
# file of the same name (without the '.sbd' extension)
|
3
|
-
class Thunderbird::
|
3
|
+
class Thunderbird::SubdirectoryPlaceholder
|
4
4
|
attr_reader :path
|
5
5
|
|
6
6
|
def initialize(path)
|
@@ -8,14 +8,14 @@ class Thunderbird::LocalFolderPlaceholder
|
|
8
8
|
end
|
9
9
|
|
10
10
|
def exists?
|
11
|
-
File.
|
11
|
+
File.exist?(path)
|
12
12
|
end
|
13
13
|
|
14
|
-
def
|
14
|
+
def regular?
|
15
15
|
File.file?(path)
|
16
16
|
end
|
17
17
|
|
18
|
-
def
|
18
|
+
def touch
|
19
19
|
FileUtils.touch path
|
20
20
|
end
|
21
21
|
end
|
data/lib/thunderbird.rb
CHANGED
@@ -1,6 +1,14 @@
|
|
1
|
+
require "os"
|
2
|
+
|
1
3
|
class Thunderbird
|
2
4
|
def data_path
|
3
|
-
|
4
|
-
|
5
|
+
case
|
6
|
+
when OS.linux?
|
7
|
+
File.join(Dir.home, ".thunderbird")
|
8
|
+
when OS.mac?
|
9
|
+
File.join(Dir.home, "Library", "Thunderbird")
|
10
|
+
when OS.windows?
|
11
|
+
File.join(ENV["APPDATA"].gsub("\\", "/"), "Thunderbird")
|
12
|
+
end
|
5
13
|
end
|
6
14
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module EmailServerHelpers
|
2
|
-
REQUESTED_ATTRIBUTES =
|
2
|
+
REQUESTED_ATTRIBUTES = ["BODY[]"].freeze
|
3
3
|
DEFAULT_EMAIL = "address@example.org".freeze
|
4
4
|
|
5
5
|
def send_email(folder, options)
|
@@ -28,7 +28,7 @@ module EmailServerHelpers
|
|
28
28
|
end
|
29
29
|
|
30
30
|
def server_message_to_body(message)
|
31
|
-
message["
|
31
|
+
message["BODY[]"]
|
32
32
|
end
|
33
33
|
|
34
34
|
def server_fetch_email(folder, uid)
|
@@ -0,0 +1,17 @@
|
|
1
|
+
describe Email::Provider::Default do
|
2
|
+
describe "#host" do
|
3
|
+
it "is unset" do
|
4
|
+
expect(subject.host).to be_nil
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
describe "#options" do
|
9
|
+
it "returns options" do
|
10
|
+
expect(subject.options).to be_a(Hash)
|
11
|
+
end
|
12
|
+
|
13
|
+
it "forces TLSv1_2" do
|
14
|
+
expect(subject.options[:ssl][:ssl_version]).to eq(:TLSv1_2)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -1,40 +1,27 @@
|
|
1
1
|
describe Email::Provider do
|
2
|
-
subject { described_class.new(:gmail) }
|
3
|
-
|
4
2
|
describe ".for_address" do
|
5
3
|
context "with known providers" do
|
6
4
|
[
|
7
|
-
["
|
8
|
-
["fastmail.fm",
|
9
|
-
|
10
|
-
|
5
|
+
["fastmail.com", "Fastmail .com", Email::Provider::Fastmail],
|
6
|
+
["fastmail.fm", "Fastmail .fm", Email::Provider::Fastmail],
|
7
|
+
["gmail.com", "GMail", Email::Provider::GMail],
|
8
|
+
["icloud.com", "Apple Mail icloud.com", Email::Provider::AppleMail],
|
9
|
+
["mac.com", "Apple Mail mac.com", Email::Provider::AppleMail],
|
10
|
+
["me.com", "Apple Mail me.com", Email::Provider::AppleMail]
|
11
|
+
].each do |domain, name, klass|
|
12
|
+
it "recognizes #{name} addresses" do
|
11
13
|
address = "foo@#{domain}"
|
12
|
-
expect(described_class.for_address(address)
|
14
|
+
expect(described_class.for_address(address)).to be_a(klass)
|
13
15
|
end
|
14
16
|
end
|
15
17
|
end
|
16
18
|
|
17
19
|
context "with unknown providers" do
|
18
20
|
it "returns a default provider" do
|
19
|
-
result = described_class.for_address("foo@unknown.com")
|
20
|
-
expect(result).to eq(:default)
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
describe "#options" do
|
26
|
-
it "returns options" do
|
27
|
-
expect(subject.options).to be_a(Hash)
|
28
|
-
end
|
21
|
+
result = described_class.for_address("foo@unknown.com")
|
29
22
|
|
30
|
-
|
31
|
-
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
describe "#host" do
|
36
|
-
it "returns host" do
|
37
|
-
expect(subject.host).to eq("imap.gmail.com")
|
23
|
+
expect(result).to be_a(Email::Provider::Default)
|
24
|
+
end
|
38
25
|
end
|
39
26
|
end
|
40
27
|
end
|
@@ -14,8 +14,10 @@ describe Imap::Backup::Account::Connection do
|
|
14
14
|
|
15
15
|
subject { described_class.new(options) }
|
16
16
|
|
17
|
-
let(:
|
18
|
-
instance_double(
|
17
|
+
let(:client) do
|
18
|
+
instance_double(
|
19
|
+
Imap::Backup::Client::Default, authenticate: nil, login: nil, disconnect: nil
|
20
|
+
)
|
19
21
|
end
|
20
22
|
let(:imap_folders) { [] }
|
21
23
|
let(:options) do
|
@@ -45,15 +47,14 @@ describe Imap::Backup::Account::Connection do
|
|
45
47
|
let(:new_uid_validity) { nil }
|
46
48
|
|
47
49
|
before do
|
48
|
-
allow(
|
49
|
-
allow(
|
50
|
-
allow(imap).to receive(:list).with(ROOT_NAME, "*") { imap_folders }
|
50
|
+
allow(Imap::Backup::Client::Default).to receive(:new) { client }
|
51
|
+
allow(client).to receive(:list) { imap_folders }
|
51
52
|
allow(Imap::Backup::Utils).to receive(:make_folder)
|
52
53
|
end
|
53
54
|
|
54
55
|
shared_examples "connects to IMAP" do
|
55
56
|
it "logs in to the imap server" do
|
56
|
-
expect(
|
57
|
+
expect(client).to have_received(:login)
|
57
58
|
end
|
58
59
|
end
|
59
60
|
|
@@ -76,48 +77,34 @@ describe Imap::Backup::Account::Connection do
|
|
76
77
|
end
|
77
78
|
end
|
78
79
|
|
79
|
-
describe "#
|
80
|
-
let(:result) { subject.
|
80
|
+
describe "#client" do
|
81
|
+
let(:result) { subject.client }
|
81
82
|
|
82
83
|
it "returns the IMAP connection" do
|
83
|
-
expect(result).to eq(
|
84
|
+
expect(result).to eq(client)
|
84
85
|
end
|
85
86
|
|
86
87
|
it "uses the password" do
|
87
88
|
result
|
88
89
|
|
89
|
-
expect(
|
90
|
-
end
|
91
|
-
|
92
|
-
context "with the GMail IMAP server" do
|
93
|
-
let(:server) { GMAIL_IMAP_SERVER }
|
94
|
-
let(:refresh_token) { true }
|
95
|
-
let(:result) { nil }
|
96
|
-
|
97
|
-
context "when the password is not our copy of a GMail refresh token" do
|
98
|
-
it "uses the password" do
|
99
|
-
subject.imap
|
100
|
-
|
101
|
-
expect(imap).to have_received(:login).with(USERNAME, PASSWORD)
|
102
|
-
end
|
103
|
-
end
|
90
|
+
expect(client).to have_received(:login).with(USERNAME, PASSWORD)
|
104
91
|
end
|
105
92
|
|
106
93
|
context "when the first login attempt fails" do
|
107
94
|
before do
|
108
95
|
outcomes = [-> { raise EOFError }, -> { true }]
|
109
|
-
allow(
|
96
|
+
allow(client).to receive(:login) { outcomes.shift.call }
|
110
97
|
end
|
111
98
|
|
112
99
|
it "retries" do
|
113
|
-
subject.
|
100
|
+
subject.client
|
114
101
|
|
115
|
-
expect(
|
102
|
+
expect(client).to have_received(:login).twice
|
116
103
|
end
|
117
104
|
end
|
118
105
|
|
119
106
|
context "when run" do
|
120
|
-
before { subject.
|
107
|
+
before { subject.client }
|
121
108
|
|
122
109
|
include_examples "connects to IMAP"
|
123
110
|
end
|
@@ -125,22 +112,12 @@ describe Imap::Backup::Account::Connection do
|
|
125
112
|
|
126
113
|
describe "#folders" do
|
127
114
|
let(:imap_folders) do
|
128
|
-
[
|
115
|
+
[BACKUP_FOLDER]
|
129
116
|
end
|
130
117
|
|
131
118
|
it "returns the list of folders" do
|
132
119
|
expect(subject.folders).to eq([BACKUP_FOLDER])
|
133
120
|
end
|
134
|
-
|
135
|
-
context "with non-ASCII folder names" do
|
136
|
-
let(:imap_folders) do
|
137
|
-
[instance_double(Net::IMAP::MailboxList, name: "Gel&APY-scht")]
|
138
|
-
end
|
139
|
-
|
140
|
-
it "converts them to UTF-8" do
|
141
|
-
expect(subject.folders).to eq(["Gelöscht"])
|
142
|
-
end
|
143
|
-
end
|
144
121
|
end
|
145
122
|
|
146
123
|
describe "#status" do
|
@@ -208,9 +185,7 @@ describe Imap::Backup::Account::Connection do
|
|
208
185
|
end
|
209
186
|
|
210
187
|
context "without supplied config_folders" do
|
211
|
-
let(:imap_folders)
|
212
|
-
[instance_double(Net::IMAP::MailboxList, name: ROOT_NAME)]
|
213
|
-
end
|
188
|
+
let(:imap_folders) { [ROOT_NAME] }
|
214
189
|
|
215
190
|
before do
|
216
191
|
allow(Imap::Backup::Account::Folder).to receive(:new).
|
@@ -241,7 +216,7 @@ describe Imap::Backup::Account::Connection do
|
|
241
216
|
|
242
217
|
context "when the imap server doesn't return folders" do
|
243
218
|
let(:config_folders) { nil }
|
244
|
-
let(:imap_folders) {
|
219
|
+
let(:imap_folders) { [] }
|
245
220
|
|
246
221
|
it "fails" do
|
247
222
|
expect do
|
@@ -389,10 +364,10 @@ describe Imap::Backup::Account::Connection do
|
|
389
364
|
|
390
365
|
describe "#reconnect" do
|
391
366
|
context "when the IMAP connection has been used" do
|
392
|
-
before { subject.
|
367
|
+
before { subject.client }
|
393
368
|
|
394
369
|
it "disconnects from the server" do
|
395
|
-
expect(
|
370
|
+
expect(client).to receive(:disconnect)
|
396
371
|
|
397
372
|
subject.reconnect
|
398
373
|
end
|
@@ -400,26 +375,26 @@ describe Imap::Backup::Account::Connection do
|
|
400
375
|
|
401
376
|
context "when the IMAP connection has not been used" do
|
402
377
|
it "does not disconnect from the server" do
|
403
|
-
expect(
|
378
|
+
expect(client).to_not receive(:disconnect)
|
404
379
|
|
405
380
|
subject.reconnect
|
406
381
|
end
|
407
382
|
end
|
408
383
|
|
409
384
|
it "causes reconnection on future access" do
|
410
|
-
expect(
|
385
|
+
expect(Imap::Backup::Client::Default).to receive(:new)
|
411
386
|
|
412
387
|
subject.reconnect
|
413
|
-
subject.
|
388
|
+
subject.client
|
414
389
|
end
|
415
390
|
end
|
416
391
|
|
417
392
|
describe "#disconnect" do
|
418
393
|
context "when the IMAP connection has been used" do
|
419
394
|
it "disconnects from the server" do
|
420
|
-
subject.
|
395
|
+
subject.client
|
421
396
|
|
422
|
-
expect(
|
397
|
+
expect(client).to receive(:disconnect)
|
423
398
|
|
424
399
|
subject.disconnect
|
425
400
|
end
|
@@ -427,7 +402,7 @@ describe Imap::Backup::Account::Connection do
|
|
427
402
|
|
428
403
|
context "when the IMAP connection has not been used" do
|
429
404
|
it "does not disconnect from the server" do
|
430
|
-
expect(
|
405
|
+
expect(client).to_not receive(:disconnect)
|
431
406
|
|
432
407
|
subject.disconnect
|
433
408
|
end
|