imap-backup 1.0.9 → 1.0.10
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 +7 -0
- data/.travis.yml +1 -0
- data/Rakefile +0 -5
- data/imap-backup.gemspec +5 -5
- data/lib/email/mboxrd/message.rb +1 -1
- data/lib/imap/backup.rb +3 -1
- data/lib/imap/backup/account/connection.rb +9 -7
- data/lib/imap/backup/account/folder.rb +6 -4
- data/lib/imap/backup/configuration/account.rb +9 -7
- data/lib/imap/backup/configuration/asker.rb +7 -5
- data/lib/imap/backup/configuration/connection_tester.rb +5 -3
- data/lib/imap/backup/configuration/folder_chooser.rb +10 -8
- data/lib/imap/backup/configuration/list.rb +8 -6
- data/lib/imap/backup/configuration/setup.rb +7 -5
- data/lib/imap/backup/configuration/store.rb +7 -5
- data/lib/imap/backup/serializer/base.rb +2 -1
- data/lib/imap/backup/serializer/directory.rb +5 -3
- data/lib/imap/backup/serializer/mbox.rb +10 -5
- data/lib/imap/backup/utils.rb +23 -30
- data/lib/imap/backup/version.rb +7 -7
- data/spec/spec_helper.rb +10 -27
- data/spec/support/higline_test_helpers.rb +8 -0
- data/spec/support/silence_logging.rb +7 -0
- data/spec/unit/account/connection_spec.rb +1 -1
- data/spec/unit/account/folder_spec.rb +33 -52
- data/spec/unit/configuration/asker_spec.rb +46 -5
- data/spec/unit/configuration/folder_chooser_spec.rb +62 -102
- data/spec/unit/configuration/list_spec.rb +40 -48
- data/spec/unit/configuration/setup_spec.rb +41 -62
- data/spec/unit/configuration/store_spec.rb +107 -99
- data/spec/unit/downloader_spec.rb +8 -8
- data/spec/unit/email/mboxrd/message_spec.rb +9 -19
- data/spec/unit/serializer/base_spec.rb +7 -5
- data/spec/unit/serializer/directory_spec.rb +30 -38
- data/spec/unit/serializer/mbox_spec.rb +64 -58
- data/spec/unit/utils_spec.rb +67 -41
- metadata +107 -141
@@ -4,16 +4,16 @@ require 'spec_helper'
|
|
4
4
|
describe Imap::Backup::Downloader do
|
5
5
|
context 'with account and downloader' do
|
6
6
|
let(:local_path) { '/base/path' }
|
7
|
-
let(:stat) {
|
7
|
+
let(:stat) { double('File::Stat', :mode => 0700) }
|
8
8
|
let(:message) do
|
9
9
|
{
|
10
10
|
'RFC822' => 'the body',
|
11
11
|
'other' => 'xxx'
|
12
12
|
}
|
13
13
|
end
|
14
|
-
let(:folder) {
|
14
|
+
let(:folder) { double('Imap::Backup::Account::Folder', :fetch => message) }
|
15
15
|
let(:serializer) do
|
16
|
-
|
16
|
+
double(
|
17
17
|
'Imap::Backup::Serializer',
|
18
18
|
:prepare => nil,
|
19
19
|
:exist? => true,
|
@@ -22,9 +22,9 @@ describe Imap::Backup::Downloader do
|
|
22
22
|
)
|
23
23
|
end
|
24
24
|
|
25
|
-
before { File.
|
25
|
+
before { allow(File).to receive(:stat).with(local_path).and_return(stat) }
|
26
26
|
|
27
|
-
subject {
|
27
|
+
subject { described_class.new(folder, serializer) }
|
28
28
|
|
29
29
|
context '#run' do
|
30
30
|
context 'with folder' do
|
@@ -36,11 +36,11 @@ describe Imap::Backup::Downloader do
|
|
36
36
|
|
37
37
|
context 'with messages' do
|
38
38
|
before :each do
|
39
|
-
folder.
|
39
|
+
allow(folder).to receive(:uids).and_return(['123', '999', '1234'])
|
40
40
|
end
|
41
41
|
|
42
42
|
it 'should skip messages that are downloaded' do
|
43
|
-
File.
|
43
|
+
allow(File).to receive(:exist?).and_return(true)
|
44
44
|
|
45
45
|
serializer.should_not_receive(:fetch)
|
46
46
|
|
@@ -56,7 +56,7 @@ describe Imap::Backup::Downloader do
|
|
56
56
|
|
57
57
|
context 'to download' do
|
58
58
|
before :each do
|
59
|
-
serializer.
|
59
|
+
allow(serializer).to receive(:exist?) do |uid|
|
60
60
|
if uid == '123'
|
61
61
|
true
|
62
62
|
else
|
@@ -5,34 +5,24 @@ require 'spec_helper'
|
|
5
5
|
describe Email::Mboxrd::Message do
|
6
6
|
let(:from) { 'me@example.com' }
|
7
7
|
let(:date) { DateTime.new(2012, 12, 13, 18, 23, 45) }
|
8
|
-
let(:message_body)
|
9
|
-
|
8
|
+
let(:message_body) do
|
9
|
+
double('Body', :clone => cloned_message_body, :force_encoding => nil)
|
10
|
+
end
|
11
|
+
let(:cloned_message_body) { "Foo\nBar\nFrom at the beginning of the line\n>>From quoted" }
|
12
|
+
|
13
|
+
subject { described_class.new(message_body) }
|
10
14
|
|
11
15
|
context '#to_s' do
|
12
|
-
let(:mail)
|
13
|
-
mail = stub('Mail')
|
14
|
-
mail.stub(:from).and_return([from])
|
15
|
-
mail.stub(:date).and_return(date)
|
16
|
-
mail
|
17
|
-
end
|
16
|
+
let(:mail) { double('Mail', :from =>[from], :date => date) }
|
18
17
|
|
19
18
|
before do
|
20
|
-
Mail.
|
19
|
+
allow(Mail).to receive(:new).with(cloned_message_body).and_return(mail)
|
21
20
|
end
|
22
21
|
|
23
22
|
it 'does not modify the message' do
|
24
|
-
message_body2 = message_body.clone
|
25
|
-
|
26
|
-
message_body.should_receive(:clone).and_return(message_body2)
|
27
|
-
message_body.should_not_receive(:force_encoding).with('binary')
|
28
|
-
|
29
23
|
subject.to_s
|
30
|
-
end
|
31
24
|
|
32
|
-
|
33
|
-
Mail.should_receive(:new).with(message_body).and_return(mail)
|
34
|
-
|
35
|
-
subject.to_s
|
25
|
+
expect(message_body).to_not have_received(:force_encoding).with('binary')
|
36
26
|
end
|
37
27
|
|
38
28
|
it "adds a 'From ' line at the start" do
|
@@ -4,14 +4,16 @@ require 'spec_helper'
|
|
4
4
|
|
5
5
|
describe Imap::Backup::Serializer::Base do
|
6
6
|
context '#initialize' do
|
7
|
-
let(:stat) {
|
7
|
+
let(:stat) { double('File::Stat', :mode => 0345) }
|
8
8
|
|
9
|
-
|
10
|
-
File.
|
11
|
-
File.
|
9
|
+
before do
|
10
|
+
allow(File).to receive(:exist?).with('/base/path').and_return(true)
|
11
|
+
allow(File).to receive(:stat).with('/base/path').and_return(stat)
|
12
|
+
end
|
12
13
|
|
14
|
+
it 'should fail if file permissions are to lax' do
|
13
15
|
expect do
|
14
|
-
|
16
|
+
described_class.new('/base/path', 'my_folder')
|
15
17
|
end.to raise_error(RuntimeError, "Permissions on '/base/path' should be 0700, not 0345")
|
16
18
|
end
|
17
19
|
end
|
@@ -2,77 +2,69 @@
|
|
2
2
|
require 'spec_helper'
|
3
3
|
|
4
4
|
describe Imap::Backup::Serializer::Directory do
|
5
|
-
let(:stat) {
|
5
|
+
let(:stat) { double('File::Stat', :mode => 0700) }
|
6
6
|
let(:files) { ['00000123.json', '000001.json'] }
|
7
|
+
let(:base) { '/base/path' }
|
8
|
+
let(:folder) { '/base/path/my_folder' }
|
9
|
+
let(:folder_exists) { true }
|
7
10
|
|
8
11
|
before do
|
9
|
-
|
10
|
-
FileUtils.
|
11
|
-
|
12
|
-
File.
|
12
|
+
allow(FileUtils).to receive(:mkdir_p)
|
13
|
+
allow(FileUtils).to receive(:chmod)
|
14
|
+
allow(File).to receive(:stat).with(base).and_return(stat)
|
15
|
+
allow(File).to receive(:exist?).with(base).and_return(true)
|
16
|
+
allow(File).to receive(:exist?).with(folder).and_return(folder_exists)
|
13
17
|
end
|
14
18
|
|
15
|
-
subject {
|
19
|
+
subject { described_class.new(base, 'my_folder') }
|
16
20
|
|
17
21
|
context '#uids' do
|
18
|
-
|
19
|
-
|
20
|
-
|
22
|
+
before do
|
23
|
+
allow(Dir).to receive(:open).with(folder).and_return(files)
|
24
|
+
end
|
21
25
|
|
26
|
+
it 'returns the backed-up uids' do
|
22
27
|
subject.uids.should == [1, 123]
|
23
28
|
end
|
24
29
|
|
25
|
-
|
26
|
-
|
30
|
+
context 'if the directory does not exist' do
|
31
|
+
let(:folder_exists) { false }
|
27
32
|
|
28
|
-
|
33
|
+
it 'returns an empty array' do
|
34
|
+
subject.uids.should == []
|
35
|
+
end
|
29
36
|
end
|
30
37
|
end
|
31
38
|
|
32
39
|
context '#exist?' do
|
33
|
-
it '
|
34
|
-
File.
|
40
|
+
it 'checks if the file exists' do
|
41
|
+
allow(File).to receive(:exist?).with(%r{/base/path/my_folder/0+123.json}).and_return(true)
|
35
42
|
|
36
43
|
subject.exist?(123).should be_true
|
37
44
|
end
|
38
45
|
end
|
39
46
|
|
40
47
|
context '#save' do
|
41
|
-
let(:message)
|
42
|
-
|
43
|
-
'RFC822' => 'the body',
|
44
|
-
'other' => 'xxx'
|
45
|
-
}
|
46
|
-
end
|
47
|
-
let(:file) { stub('File', :write => nil) }
|
48
|
+
let(:message) { {'RFC822' => 'the body', 'other' => 'xxx'} }
|
49
|
+
let(:file) { double('File', :write => nil) }
|
48
50
|
|
49
51
|
before do
|
50
|
-
File.
|
51
|
-
|
52
|
-
File.stub!(:open) do |&block|
|
52
|
+
allow(File).to receive(:exist?).with(%r{/base/path/my_folder/0+1234.json}).and_return(true)
|
53
|
+
allow(File).to receive(:open) do |&block|
|
53
54
|
block.call file
|
54
55
|
end
|
55
56
|
end
|
56
57
|
|
57
|
-
it '
|
58
|
-
File.should_receive(:open) do |&block|
|
59
|
-
block.call file
|
60
|
-
end
|
61
|
-
file.should_receive(:write).with(/the body/)
|
62
|
-
|
58
|
+
it 'saves messages' do
|
63
59
|
subject.save('1234', message)
|
64
|
-
end
|
65
|
-
|
66
|
-
it 'should JSON encode messages' do
|
67
|
-
message.should_receive(:to_json)
|
68
60
|
|
69
|
-
|
61
|
+
expect(file).to have_received(:write).with(message.to_json)
|
70
62
|
end
|
71
63
|
|
72
|
-
it '
|
73
|
-
FileUtils.should_receive(:chmod).with(0600, /0+1234.json$/)
|
74
|
-
|
64
|
+
it 'sets file permissions' do
|
75
65
|
subject.save(1234, message)
|
66
|
+
|
67
|
+
expect(FileUtils).to have_received(:chmod).with(0600, /0+1234.json$/)
|
76
68
|
end
|
77
69
|
end
|
78
70
|
end
|
@@ -3,109 +3,115 @@
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
5
|
describe Imap::Backup::Serializer::Mbox do
|
6
|
-
let(:stat) {
|
6
|
+
let(:stat) { double('File::Stat', :mode => 0700) }
|
7
|
+
let(:base_path) { '/base/path' }
|
7
8
|
let(:mbox_pathname) { '/base/path/my/folder.mbox' }
|
9
|
+
let(:mbox_exists) { true }
|
8
10
|
let(:imap_pathname) { '/base/path/my/folder.imap' }
|
11
|
+
let(:imap_exists) { true }
|
9
12
|
|
10
13
|
before do
|
11
|
-
|
12
|
-
File.
|
13
|
-
|
14
|
+
allow(Imap::Backup::Utils).to receive(:make_folder)
|
15
|
+
allow(File).to receive(:exist?).with(base_path).and_return(true)
|
16
|
+
allow(File).to receive(:stat).with(base_path).and_return(stat)
|
17
|
+
allow(File).to receive(:exist?).with(mbox_pathname).and_return(mbox_exists)
|
18
|
+
allow(File).to receive(:exist?).with(imap_pathname).and_return(imap_exists)
|
14
19
|
end
|
15
20
|
|
16
21
|
context '#initialize' do
|
17
|
-
before do
|
18
|
-
File.stub(:exist?).with(mbox_pathname).and_return(true)
|
19
|
-
File.stub(:exist?).with(imap_pathname).and_return(true)
|
20
|
-
end
|
21
|
-
|
22
22
|
it 'creates the containing directory' do
|
23
|
-
|
23
|
+
described_class.new(base_path, 'my/folder')
|
24
24
|
|
25
|
-
Imap::Backup::
|
25
|
+
expect(Imap::Backup::Utils).to have_received(:make_folder).with(base_path, 'my', 0700)
|
26
26
|
end
|
27
27
|
|
28
28
|
context 'mbox and imap files' do
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
29
|
+
context "if mbox exists and imap doesn't" do
|
30
|
+
let(:imap_exists) { false }
|
31
|
+
|
32
|
+
it 'fails' do
|
33
|
+
expect {
|
34
|
+
described_class.new(base_path, 'my/folder')
|
35
|
+
}.to raise_error(RuntimeError, '.imap file missing')
|
36
|
+
end
|
34
37
|
end
|
35
38
|
|
36
|
-
|
37
|
-
|
39
|
+
context "if imap exists and mbox doesn't" do
|
40
|
+
let(:mbox_exists) { false }
|
38
41
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
it "fails if imap exists and mbox doesn't" do
|
45
|
-
File.stub(:exist?).with(mbox_pathname).and_return(false)
|
46
|
-
|
47
|
-
expect {
|
48
|
-
Imap::Backup::Serializer::Mbox.new('/base/path', 'my/folder')
|
49
|
-
}.to raise_error(RuntimeError, '.mbox file missing')
|
42
|
+
it 'fails' do
|
43
|
+
expect {
|
44
|
+
described_class.new(base_path, 'my/folder')
|
45
|
+
}.to raise_error(RuntimeError, '.mbox file missing')
|
46
|
+
end
|
50
47
|
end
|
51
48
|
end
|
52
49
|
end
|
53
50
|
|
54
51
|
context 'instance methods' do
|
52
|
+
let(:ids) { %w(1 123) }
|
53
|
+
|
55
54
|
before do
|
56
|
-
|
57
|
-
File.stub(:exist?).with(imap_pathname).and_return(true)
|
58
|
-
CSV.stub(:foreach) do |&block|
|
59
|
-
block.call ['1']
|
60
|
-
block.call ['123']
|
61
|
-
end
|
55
|
+
allow(CSV).to receive(:foreach) { |&b| ids.each { |id| b.call [id] } }
|
62
56
|
end
|
63
57
|
|
64
|
-
subject {
|
58
|
+
subject { described_class.new(base_path, 'my/folder') }
|
65
59
|
|
66
60
|
context '#uids' do
|
67
61
|
it 'returns the backed-up uids' do
|
68
|
-
|
69
|
-
File.should_receive(:exist?).with(imap_pathname).and_return(true)
|
70
|
-
|
71
|
-
expect(subject.uids).to eq(['1', '123'])
|
62
|
+
expect(subject.uids).to eq(ids)
|
72
63
|
end
|
73
64
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
File.should_receive(:exist?).with(mbox_pathname).and_return(false)
|
78
|
-
File.should_receive(:exist?).with(imap_pathname).and_return(false)
|
65
|
+
context 'if the mbox does not exist' do
|
66
|
+
let(:mbox_exists) { false }
|
67
|
+
let(:imap_exists) { false }
|
79
68
|
|
80
|
-
|
69
|
+
it 'returns an empty Array' do
|
70
|
+
expect(subject.uids).to eq([])
|
71
|
+
end
|
81
72
|
end
|
82
73
|
end
|
83
74
|
|
84
75
|
context '#save' do
|
85
76
|
let(:mbox_formatted_message) { 'message in mbox format' }
|
86
77
|
let(:message_uid) { '999' }
|
87
|
-
let(:message) {
|
88
|
-
let(:mbox_file) {
|
89
|
-
let(:imap_file) {
|
78
|
+
let(:message) { double('Email::Mboxrd::Message', :to_s => mbox_formatted_message) }
|
79
|
+
let(:mbox_file) { double('File - mbox', :write => nil, :close => nil) }
|
80
|
+
let(:imap_file) { double('File - imap', :write => nil, :close => nil) }
|
90
81
|
|
91
82
|
before do
|
92
|
-
Email::Mboxrd::Message.
|
93
|
-
File.
|
94
|
-
File.
|
95
|
-
mbox_file.stub(:write).with(mbox_formatted_message)
|
96
|
-
imap_file.stub(:write).with(message_uid + "\n")
|
83
|
+
allow(Email::Mboxrd::Message).to receive(:new).and_return(message)
|
84
|
+
allow(File).to receive(:open).with(mbox_pathname, 'ab').and_return(mbox_file)
|
85
|
+
allow(File).to receive(:open).with(imap_pathname, 'ab').and_return(imap_file)
|
97
86
|
end
|
98
87
|
|
99
88
|
it 'saves the message to the mbox' do
|
100
|
-
mbox_file.should_receive(:write).with(mbox_formatted_message)
|
101
|
-
|
102
89
|
subject.save(message_uid, "The\nemail\n")
|
90
|
+
|
91
|
+
expect(mbox_file).to have_received(:write).with(mbox_formatted_message)
|
103
92
|
end
|
104
93
|
|
105
94
|
it 'saves the uid to the imap file' do
|
106
|
-
imap_file.should_receive(:write).with(message_uid + "\n")
|
107
|
-
|
108
95
|
subject.save(message_uid, "The\nemail\n")
|
96
|
+
|
97
|
+
expect(imap_file).to have_received(:write).with(message_uid + "\n")
|
98
|
+
end
|
99
|
+
|
100
|
+
context 'when the message causes parsing errors' do
|
101
|
+
before do
|
102
|
+
allow(message).to receive(:to_s).and_raise(ArgumentError)
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'skips the message' do
|
106
|
+
subject.save(message_uid, "The\nemail\n")
|
107
|
+
expect(mbox_file).to_not have_received(:write)
|
108
|
+
end
|
109
|
+
|
110
|
+
it 'does not fail' do
|
111
|
+
expect do
|
112
|
+
subject.save(message_uid, "The\nemail\n")
|
113
|
+
end.to_not raise_error
|
114
|
+
end
|
109
115
|
end
|
110
116
|
end
|
111
117
|
end
|
data/spec/unit/utils_spec.rb
CHANGED
@@ -2,67 +2,93 @@
|
|
2
2
|
require 'spec_helper'
|
3
3
|
|
4
4
|
describe Imap::Backup::Utils do
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
5
|
+
let(:filename) { 'foobar' }
|
6
|
+
let(:stat) { double('File::Stat', :mode => mode) }
|
7
|
+
let(:mode) { 0777 }
|
8
|
+
let(:exists) { true }
|
9
|
+
|
10
|
+
before do
|
11
|
+
allow(File).to receive(:stat).and_return(stat)
|
12
|
+
allow(File).to receive(:exist?).with(filename).and_return(exists)
|
13
|
+
end
|
13
14
|
|
14
|
-
|
15
|
+
context '.check_permissions' do
|
16
|
+
let(:requested) { 0345 }
|
17
|
+
|
18
|
+
context 'with existing files' do
|
19
|
+
[
|
20
|
+
[0100, 'less than the limit', true],
|
21
|
+
[0345, 'equal to the limit', true],
|
22
|
+
[0777, 'over the limit', false],
|
23
|
+
].each do |mode, description, success|
|
24
|
+
context "when permissions are #{description}" do
|
25
|
+
let(:mode) { mode }
|
26
|
+
|
27
|
+
if success
|
28
|
+
it 'succeeds' do
|
29
|
+
described_class.check_permissions(filename, requested)
|
30
|
+
end
|
31
|
+
else
|
32
|
+
it 'fails' do
|
33
|
+
expect do
|
34
|
+
described_class.check_permissions(filename, requested)
|
35
|
+
end.to raise_error(RuntimeError, format("Permissions on '%s' should be 0%o, not 0%o", filename, requested, mode))
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
15
40
|
end
|
16
41
|
|
17
|
-
|
18
|
-
|
19
|
-
|
42
|
+
context 'with non-existent files' do
|
43
|
+
let(:exists) { false }
|
44
|
+
let(:mode) { 0111 }
|
20
45
|
|
21
|
-
|
22
|
-
|
23
|
-
end
|
46
|
+
it 'succeeds' do
|
47
|
+
described_class.check_permissions(filename, requested)
|
48
|
+
end
|
24
49
|
end
|
50
|
+
end
|
25
51
|
|
26
|
-
|
27
|
-
|
28
|
-
|
52
|
+
context '.stat' do
|
53
|
+
context 'with existing files' do
|
54
|
+
let(:mode) { 02345 }
|
29
55
|
|
30
|
-
|
31
|
-
|
32
|
-
end
|
56
|
+
it 'is the last 9 bits of the file mode' do
|
57
|
+
expect(described_class.stat(filename)).to eq(0345)
|
58
|
+
end
|
33
59
|
end
|
34
60
|
|
35
|
-
|
36
|
-
|
37
|
-
File.stub!(:stat).and_return(stat)
|
61
|
+
context 'with non-existent files' do
|
62
|
+
let(:exists) { false }
|
38
63
|
|
39
|
-
|
40
|
-
|
41
|
-
end
|
64
|
+
it 'is nil' do
|
65
|
+
expect(described_class.stat(filename)).to be_nil
|
66
|
+
end
|
42
67
|
end
|
43
68
|
end
|
44
69
|
|
45
|
-
context '
|
46
|
-
|
47
|
-
FileUtils.
|
48
|
-
|
49
|
-
Imap::Backup::Utils.make_folder('aaa', '', 0222)
|
70
|
+
context '.make_folder' do
|
71
|
+
before do
|
72
|
+
allow(FileUtils).to receive(:mkdir_p)
|
73
|
+
allow(FileUtils).to receive(:chmod)
|
50
74
|
end
|
51
75
|
|
52
|
-
it '
|
53
|
-
|
54
|
-
|
55
|
-
FileUtils.should_receive(:mkdir_p).with('/base/path/new/folder')
|
76
|
+
it 'does nothing if an empty path is supplied' do
|
77
|
+
described_class.make_folder('aaa', '', 0222)
|
56
78
|
|
57
|
-
|
79
|
+
expect(FileUtils).to_not have_received(:mkdir_p)
|
58
80
|
end
|
59
81
|
|
60
|
-
it '
|
61
|
-
|
82
|
+
it 'creates the path' do
|
83
|
+
described_class.make_folder('/base/path', 'new/folder', 0222)
|
84
|
+
|
85
|
+
expect(FileUtils).to have_received(:mkdir_p).with('/base/path/new/folder')
|
86
|
+
end
|
62
87
|
|
63
|
-
|
88
|
+
it 'sets permissions on the path' do
|
89
|
+
described_class.make_folder('/base/path/new', 'folder', 0222)
|
64
90
|
|
65
|
-
|
91
|
+
expect(FileUtils).to have_received(:chmod).with(0222, '/base/path/new/folder')
|
66
92
|
end
|
67
93
|
end
|
68
94
|
end
|