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