imap-backup 1.2.2 → 1.2.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/.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
|