imap-backup 1.2.2 → 1.2.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +7 -0
- data/Gemfile +1 -1
- data/Rakefile +4 -4
- data/bin/imap-backup +23 -25
- data/imap-backup.gemspec +14 -14
- data/lib/email/mboxrd/message.rb +23 -5
- data/lib/email/provider.rb +4 -4
- data/lib/imap/backup.rb +18 -18
- data/lib/imap/backup/account/connection.rb +6 -6
- data/lib/imap/backup/account/folder.rb +4 -5
- data/lib/imap/backup/configuration/account.rb +20 -22
- data/lib/imap/backup/configuration/asker.rb +8 -10
- data/lib/imap/backup/configuration/connection_tester.rb +3 -5
- data/lib/imap/backup/configuration/folder_chooser.rb +10 -12
- data/lib/imap/backup/configuration/list.rb +1 -3
- data/lib/imap/backup/configuration/setup.rb +13 -14
- data/lib/imap/backup/configuration/store.rb +7 -8
- data/lib/imap/backup/downloader.rb +0 -2
- data/lib/imap/backup/serializer/base.rb +0 -2
- data/lib/imap/backup/serializer/directory.rb +3 -4
- data/lib/imap/backup/serializer/mbox.rb +11 -12
- data/lib/imap/backup/utils.rb +2 -3
- data/lib/imap/backup/version.rb +2 -2
- data/spec/spec_helper.rb +6 -6
- data/spec/support/higline_test_helpers.rb +1 -1
- data/spec/support/shared_examples/account_flagging.rb +6 -6
- data/spec/unit/account/connection_spec.rb +50 -51
- data/spec/unit/account/folder_spec.rb +18 -19
- data/spec/unit/configuration/account_spec.rb +96 -97
- data/spec/unit/configuration/asker_spec.rb +33 -34
- data/spec/unit/configuration/connection_tester_spec.rb +18 -19
- data/spec/unit/configuration/folder_chooser_spec.rb +34 -35
- data/spec/unit/configuration/list_spec.rb +13 -14
- data/spec/unit/configuration/setup_spec.rb +46 -47
- data/spec/unit/configuration/store_spec.rb +56 -57
- data/spec/unit/downloader_spec.rb +18 -19
- data/spec/unit/email/mboxrd/message_spec.rb +55 -11
- data/spec/unit/email/provider_spec.rb +12 -12
- data/spec/unit/serializer/base_spec.rb +7 -9
- data/spec/unit/serializer/directory_spec.rb +18 -19
- data/spec/unit/serializer/mbox_spec.rb +35 -37
- data/spec/unit/utils_spec.rb +26 -27
- metadata +17 -2
@@ -1,19 +1,17 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require 'spec_helper'
|
1
|
+
require "spec_helper"
|
4
2
|
|
5
3
|
describe Imap::Backup::Serializer::Base do
|
6
|
-
context
|
7
|
-
let(:stat) { double(
|
4
|
+
context "#initialize" do
|
5
|
+
let(:stat) { double("File::Stat", mode: 0345) }
|
8
6
|
|
9
7
|
before do
|
10
|
-
allow(File).to receive(:exist?).with(
|
11
|
-
allow(File).to receive(:stat).with(
|
8
|
+
allow(File).to receive(:exist?).with("/base/path").and_return(true)
|
9
|
+
allow(File).to receive(:stat).with("/base/path").and_return(stat)
|
12
10
|
end
|
13
11
|
|
14
|
-
it
|
12
|
+
it "should fail if file permissions are to lax" do
|
15
13
|
expect do
|
16
|
-
described_class.new(
|
14
|
+
described_class.new("/base/path", "my_folder")
|
17
15
|
end.to raise_error(RuntimeError, "Permissions on '/base/path' should be 0700, not 0345")
|
18
16
|
end
|
19
17
|
end
|
@@ -1,11 +1,10 @@
|
|
1
|
-
|
2
|
-
require 'spec_helper'
|
1
|
+
require "spec_helper"
|
3
2
|
|
4
3
|
describe Imap::Backup::Serializer::Directory do
|
5
|
-
let(:stat) { double(
|
6
|
-
let(:files) { [
|
7
|
-
let(:base) {
|
8
|
-
let(:folder) {
|
4
|
+
let(:stat) { double("File::Stat", mode: 0700) }
|
5
|
+
let(:files) { ["00000123.json", "000001.json"] }
|
6
|
+
let(:base) { "/base/path" }
|
7
|
+
let(:folder) { "/base/path/my_folder" }
|
9
8
|
let(:folder_exists) { true }
|
10
9
|
|
11
10
|
before do
|
@@ -16,37 +15,37 @@ describe Imap::Backup::Serializer::Directory do
|
|
16
15
|
allow(File).to receive(:exist?).with(folder).and_return(folder_exists)
|
17
16
|
end
|
18
17
|
|
19
|
-
subject { described_class.new(base,
|
18
|
+
subject { described_class.new(base, "my_folder") }
|
20
19
|
|
21
|
-
context
|
20
|
+
context "#uids" do
|
22
21
|
before do
|
23
22
|
allow(Dir).to receive(:open).with(folder).and_return(files)
|
24
23
|
end
|
25
24
|
|
26
|
-
it
|
25
|
+
it "returns the backed-up uids" do
|
27
26
|
expect(subject.uids).to eq([1, 123])
|
28
27
|
end
|
29
28
|
|
30
|
-
context
|
29
|
+
context "if the directory does not exist" do
|
31
30
|
let(:folder_exists) { false }
|
32
31
|
|
33
|
-
it
|
32
|
+
it "returns an empty array" do
|
34
33
|
expect(subject.uids).to eq([])
|
35
34
|
end
|
36
35
|
end
|
37
36
|
end
|
38
37
|
|
39
|
-
context
|
40
|
-
it
|
38
|
+
context "#exist?" do
|
39
|
+
it "checks if the file exists" do
|
41
40
|
allow(File).to receive(:exist?).with(%r{/base/path/my_folder/0+123.json}).and_return(true)
|
42
41
|
|
43
42
|
expect(subject.exist?(123)).to be_truthy
|
44
43
|
end
|
45
44
|
end
|
46
45
|
|
47
|
-
context
|
48
|
-
let(:message) { {
|
49
|
-
let(:file) { double(
|
46
|
+
context "#save" do
|
47
|
+
let(:message) { {"RFC822" => "the body", "other" => "xxx"} }
|
48
|
+
let(:file) { double("File", write: nil) }
|
50
49
|
|
51
50
|
before do
|
52
51
|
allow(File).to receive(:exist?).with(%r{/base/path/my_folder/0+1234.json}).and_return(true)
|
@@ -55,13 +54,13 @@ describe Imap::Backup::Serializer::Directory do
|
|
55
54
|
end
|
56
55
|
end
|
57
56
|
|
58
|
-
it
|
59
|
-
subject.save(
|
57
|
+
it "saves messages" do
|
58
|
+
subject.save("1234", message)
|
60
59
|
|
61
60
|
expect(file).to have_received(:write).with(message.to_json)
|
62
61
|
end
|
63
62
|
|
64
|
-
it
|
63
|
+
it "sets file permissions" do
|
65
64
|
subject.save(1234, message)
|
66
65
|
|
67
66
|
expect(FileUtils).to have_received(:chmod).with(0600, /0+1234.json$/)
|
@@ -1,13 +1,11 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require 'spec_helper'
|
1
|
+
require "spec_helper"
|
4
2
|
|
5
3
|
describe Imap::Backup::Serializer::Mbox do
|
6
|
-
let(:stat) { double(
|
7
|
-
let(:base_path) {
|
8
|
-
let(:mbox_pathname) {
|
4
|
+
let(:stat) { double("File::Stat", mode: 0700) }
|
5
|
+
let(:base_path) { "/base/path" }
|
6
|
+
let(:mbox_pathname) { "/base/path/my/folder.mbox" }
|
9
7
|
let(:mbox_exists) { true }
|
10
|
-
let(:imap_pathname) {
|
8
|
+
let(:imap_pathname) { "/base/path/my/folder.imap" }
|
11
9
|
let(:imap_exists) { true }
|
12
10
|
|
13
11
|
before do
|
@@ -18,96 +16,96 @@ describe Imap::Backup::Serializer::Mbox do
|
|
18
16
|
allow(File).to receive(:exist?).with(imap_pathname).and_return(imap_exists)
|
19
17
|
end
|
20
18
|
|
21
|
-
context
|
22
|
-
it
|
23
|
-
described_class.new(base_path,
|
19
|
+
context "#initialize" do
|
20
|
+
it "creates the containing directory" do
|
21
|
+
described_class.new(base_path, "my/folder")
|
24
22
|
|
25
|
-
expect(Imap::Backup::Utils).to have_received(:make_folder).with(base_path,
|
23
|
+
expect(Imap::Backup::Utils).to have_received(:make_folder).with(base_path, "my", 0700)
|
26
24
|
end
|
27
25
|
|
28
|
-
context
|
26
|
+
context "mbox and imap files" do
|
29
27
|
context "if mbox exists and imap doesn't" do
|
30
28
|
let(:imap_exists) { false }
|
31
29
|
|
32
|
-
it
|
30
|
+
it "fails" do
|
33
31
|
expect {
|
34
|
-
described_class.new(base_path,
|
35
|
-
}.to raise_error(RuntimeError,
|
32
|
+
described_class.new(base_path, "my/folder")
|
33
|
+
}.to raise_error(RuntimeError, ".imap file missing")
|
36
34
|
end
|
37
35
|
end
|
38
36
|
|
39
37
|
context "if imap exists and mbox doesn't" do
|
40
38
|
let(:mbox_exists) { false }
|
41
39
|
|
42
|
-
it
|
40
|
+
it "fails" do
|
43
41
|
expect {
|
44
|
-
described_class.new(base_path,
|
45
|
-
}.to raise_error(RuntimeError,
|
42
|
+
described_class.new(base_path, "my/folder")
|
43
|
+
}.to raise_error(RuntimeError, ".mbox file missing")
|
46
44
|
end
|
47
45
|
end
|
48
46
|
end
|
49
47
|
end
|
50
48
|
|
51
|
-
context
|
49
|
+
context "instance methods" do
|
52
50
|
let(:ids) { %w(3 2 1) }
|
53
51
|
|
54
52
|
before do
|
55
53
|
allow(CSV).to receive(:foreach) { |&b| ids.each { |id| b.call [id] } }
|
56
54
|
end
|
57
55
|
|
58
|
-
subject { described_class.new(base_path,
|
56
|
+
subject { described_class.new(base_path, "my/folder") }
|
59
57
|
|
60
|
-
context
|
61
|
-
it
|
58
|
+
context "#uids" do
|
59
|
+
it "returns the backed-up uids as sorted integers" do
|
62
60
|
expect(subject.uids).to eq(ids.map(&:to_i).sort)
|
63
61
|
end
|
64
62
|
|
65
|
-
context
|
63
|
+
context "if the mbox does not exist" do
|
66
64
|
let(:mbox_exists) { false }
|
67
65
|
let(:imap_exists) { false }
|
68
66
|
|
69
|
-
it
|
67
|
+
it "returns an empty Array" do
|
70
68
|
expect(subject.uids).to eq([])
|
71
69
|
end
|
72
70
|
end
|
73
71
|
end
|
74
72
|
|
75
|
-
context
|
76
|
-
let(:mbox_formatted_message) {
|
77
|
-
let(:message_uid) {
|
78
|
-
let(:message) { double(
|
79
|
-
let(:mbox_file) { double(
|
80
|
-
let(:imap_file) { double(
|
73
|
+
context "#save" do
|
74
|
+
let(:mbox_formatted_message) { "message in mbox format" }
|
75
|
+
let(:message_uid) { "999" }
|
76
|
+
let(:message) { double("Email::Mboxrd::Message", to_s: mbox_formatted_message) }
|
77
|
+
let(:mbox_file) { double("File - mbox", write: nil, close: nil) }
|
78
|
+
let(:imap_file) { double("File - imap", write: nil, close: nil) }
|
81
79
|
|
82
80
|
before do
|
83
81
|
allow(Email::Mboxrd::Message).to receive(:new).and_return(message)
|
84
|
-
allow(File).to receive(:open).with(mbox_pathname,
|
85
|
-
allow(File).to receive(:open).with(imap_pathname,
|
82
|
+
allow(File).to receive(:open).with(mbox_pathname, "ab").and_return(mbox_file)
|
83
|
+
allow(File).to receive(:open).with(imap_pathname, "ab").and_return(imap_file)
|
86
84
|
end
|
87
85
|
|
88
|
-
it
|
86
|
+
it "saves the message to the mbox" do
|
89
87
|
subject.save(message_uid, "The\nemail\n")
|
90
88
|
|
91
89
|
expect(mbox_file).to have_received(:write).with(mbox_formatted_message)
|
92
90
|
end
|
93
91
|
|
94
|
-
it
|
92
|
+
it "saves the uid to the imap file" do
|
95
93
|
subject.save(message_uid, "The\nemail\n")
|
96
94
|
|
97
95
|
expect(imap_file).to have_received(:write).with(message_uid + "\n")
|
98
96
|
end
|
99
97
|
|
100
|
-
context
|
98
|
+
context "when the message causes parsing errors" do
|
101
99
|
before do
|
102
100
|
allow(message).to receive(:to_s).and_raise(ArgumentError)
|
103
101
|
end
|
104
102
|
|
105
|
-
it
|
103
|
+
it "skips the message" do
|
106
104
|
subject.save(message_uid, "The\nemail\n")
|
107
105
|
expect(mbox_file).to_not have_received(:write)
|
108
106
|
end
|
109
107
|
|
110
|
-
it
|
108
|
+
it "does not fail" do
|
111
109
|
expect do
|
112
110
|
subject.save(message_uid, "The\nemail\n")
|
113
111
|
end.to_not raise_error
|
data/spec/unit/utils_spec.rb
CHANGED
@@ -1,9 +1,8 @@
|
|
1
|
-
|
2
|
-
require 'spec_helper'
|
1
|
+
require "spec_helper"
|
3
2
|
|
4
3
|
describe Imap::Backup::Utils do
|
5
|
-
let(:filename) {
|
6
|
-
let(:stat) { double(
|
4
|
+
let(:filename) { "foobar" }
|
5
|
+
let(:stat) { double("File::Stat", mode: mode) }
|
7
6
|
let(:mode) { 0777 }
|
8
7
|
let(:exists) { true }
|
9
8
|
|
@@ -12,24 +11,24 @@ describe Imap::Backup::Utils do
|
|
12
11
|
allow(File).to receive(:exist?).with(filename).and_return(exists)
|
13
12
|
end
|
14
13
|
|
15
|
-
context
|
14
|
+
context ".check_permissions" do
|
16
15
|
let(:requested) { 0345 }
|
17
16
|
|
18
|
-
context
|
17
|
+
context "with existing files" do
|
19
18
|
[
|
20
|
-
[0100,
|
21
|
-
[0345,
|
22
|
-
[0777,
|
19
|
+
[0100, "less than the limit", true],
|
20
|
+
[0345, "equal to the limit", true],
|
21
|
+
[0777, "over the limit", false]
|
23
22
|
].each do |mode, description, success|
|
24
23
|
context "when permissions are #{description}" do
|
25
24
|
let(:mode) { mode }
|
26
25
|
|
27
26
|
if success
|
28
|
-
it
|
27
|
+
it "succeeds" do
|
29
28
|
described_class.check_permissions(filename, requested)
|
30
29
|
end
|
31
30
|
else
|
32
|
-
it
|
31
|
+
it "fails" do
|
33
32
|
expect do
|
34
33
|
described_class.check_permissions(filename, requested)
|
35
34
|
end.to raise_error(RuntimeError, format("Permissions on '%s' should be 0%o, not 0%o", filename, requested, mode))
|
@@ -39,56 +38,56 @@ describe Imap::Backup::Utils do
|
|
39
38
|
end
|
40
39
|
end
|
41
40
|
|
42
|
-
context
|
41
|
+
context "with non-existent files" do
|
43
42
|
let(:exists) { false }
|
44
43
|
let(:mode) { 0111 }
|
45
44
|
|
46
|
-
it
|
45
|
+
it "succeeds" do
|
47
46
|
described_class.check_permissions(filename, requested)
|
48
47
|
end
|
49
48
|
end
|
50
49
|
end
|
51
50
|
|
52
|
-
context
|
53
|
-
context
|
51
|
+
context ".stat" do
|
52
|
+
context "with existing files" do
|
54
53
|
let(:mode) { 02345 }
|
55
54
|
|
56
|
-
it
|
55
|
+
it "is the last 9 bits of the file mode" do
|
57
56
|
expect(described_class.stat(filename)).to eq(0345)
|
58
57
|
end
|
59
58
|
end
|
60
59
|
|
61
|
-
context
|
60
|
+
context "with non-existent files" do
|
62
61
|
let(:exists) { false }
|
63
62
|
|
64
|
-
it
|
63
|
+
it "is nil" do
|
65
64
|
expect(described_class.stat(filename)).to be_nil
|
66
65
|
end
|
67
66
|
end
|
68
67
|
end
|
69
68
|
|
70
|
-
context
|
69
|
+
context ".make_folder" do
|
71
70
|
before do
|
72
71
|
allow(FileUtils).to receive(:mkdir_p)
|
73
72
|
allow(FileUtils).to receive(:chmod)
|
74
73
|
end
|
75
74
|
|
76
|
-
it
|
77
|
-
described_class.make_folder(
|
75
|
+
it "does nothing if an empty path is supplied" do
|
76
|
+
described_class.make_folder("aaa", "", 0222)
|
78
77
|
|
79
78
|
expect(FileUtils).to_not have_received(:mkdir_p)
|
80
79
|
end
|
81
80
|
|
82
|
-
it
|
83
|
-
described_class.make_folder(
|
81
|
+
it "creates the path" do
|
82
|
+
described_class.make_folder("/base/path", "new/folder", 0222)
|
84
83
|
|
85
|
-
expect(FileUtils).to have_received(:mkdir_p).with(
|
84
|
+
expect(FileUtils).to have_received(:mkdir_p).with("/base/path/new/folder")
|
86
85
|
end
|
87
86
|
|
88
|
-
it
|
89
|
-
described_class.make_folder(
|
87
|
+
it "sets permissions on the path" do
|
88
|
+
described_class.make_folder("/base/path/new", "folder", 0222)
|
90
89
|
|
91
|
-
expect(FileUtils).to have_received(:chmod).with(0222,
|
90
|
+
expect(FileUtils).to have_received(:chmod).with(0222, "/base/path/new/folder")
|
92
91
|
end
|
93
92
|
end
|
94
93
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: imap-backup
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.2.
|
4
|
+
version: 1.2.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joe Yates
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-08-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -80,6 +80,20 @@ dependencies:
|
|
80
80
|
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: 3.0.0
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rubocop-rspec
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
83
97
|
- !ruby/object:Gem::Dependency
|
84
98
|
name: simplecov
|
85
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -103,6 +117,7 @@ extensions: []
|
|
103
117
|
extra_rdoc_files: []
|
104
118
|
files:
|
105
119
|
- ".gitignore"
|
120
|
+
- ".rubocop.yml"
|
106
121
|
- ".travis.yml"
|
107
122
|
- Gemfile
|
108
123
|
- LICENSE
|