imap-backup 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,47 @@
1
+ # encoding: utf-8
2
+ load File.expand_path( '../../spec_helper.rb', File.dirname(__FILE__) )
3
+
4
+ describe Imap::Backup::Configuration::ConnectionTester do
5
+
6
+ context '.test' do
7
+
8
+ it 'should try to connect' do
9
+ Imap::Backup::Account::Connection.should_receive(:new).with('foo')
10
+
11
+ Imap::Backup::Configuration::ConnectionTester.test('foo')
12
+ end
13
+
14
+ it 'should return success if the connection works' do
15
+ Imap::Backup::Account::Connection.stub!(:new).
16
+ with('foo')
17
+
18
+ result = Imap::Backup::Configuration::ConnectionTester.test('foo')
19
+
20
+ result.should =~ /successful/
21
+ end
22
+
23
+ it 'should handle no response' do
24
+ e = Net::IMAP::NoResponseError.new(stub('o', :data => stub('foo', :text => 'bar')))
25
+ Imap::Backup::Account::Connection.stub!(:new).
26
+ with('foo').
27
+ and_raise(e)
28
+
29
+ result = Imap::Backup::Configuration::ConnectionTester.test('foo')
30
+
31
+ result.should =~ /no response/i
32
+ end
33
+
34
+ it 'should handle other errors' do
35
+ Imap::Backup::Account::Connection.stub!(:new).
36
+ with('foo').
37
+ and_raise('error')
38
+
39
+ result = Imap::Backup::Configuration::ConnectionTester.test('foo')
40
+
41
+ result.should =~ /unexpected error/i
42
+ end
43
+
44
+ end
45
+
46
+ end
47
+
@@ -0,0 +1,131 @@
1
+ # encoding: utf-8
2
+ load File.expand_path( '../../spec_helper.rb', File.dirname(__FILE__) )
3
+
4
+ describe Imap::Backup::Configuration::FolderChooser do
5
+
6
+ include HighLineTestHelpers
7
+ include InputOutputTestHelpers
8
+
9
+ context '#run' do
10
+
11
+ before :each do
12
+ empty_account = {
13
+ :folders => []
14
+ }
15
+ @connection = setup_account(empty_account, [])
16
+ @input, @output = prepare_highline
17
+ end
18
+
19
+ def setup_account(account, remote_folders)
20
+ @account = account
21
+ connection = stub('Imap::Backup::Account::Connection')
22
+ connection.stub!(:folders).and_return(remote_folders)
23
+ Imap::Backup::Account::Connection.stub!(:new).with(account).and_return(connection)
24
+ connection
25
+ end
26
+
27
+ subject { Imap::Backup::Configuration::FolderChooser.new(@account) }
28
+
29
+ it 'should connect to the account' do
30
+ Imap::Backup::Account::Connection.should_receive(:new).with(@account).and_return(@connection)
31
+
32
+ subject.run
33
+ end
34
+
35
+ it 'should handle connection errors' do
36
+ Imap::Backup::Account::Connection.should_receive(:new).with(@account).and_raise('error')
37
+ Imap::Backup::Configuration::Setup.highline.should_receive(:ask).with('Press a key ')
38
+
39
+ capturing_output do
40
+ subject.run
41
+ end.should =~ /connection failed/i
42
+ end
43
+
44
+ it 'should get a list of account folders' do
45
+ @connection.should_receive(:folders).and_return([])
46
+
47
+ subject.run
48
+ end
49
+
50
+ it 'should show the menu' do
51
+ subject.run
52
+
53
+ @output.string.should =~ %r{Add/remove folders}
54
+ end
55
+
56
+ it 'should return to the account menu' do
57
+ @input.should_receive(:gets).and_return("return\n")
58
+
59
+ subject.run
60
+
61
+ @output.string.should =~ %r{return to the account menu}
62
+ end
63
+
64
+ context 'folder listing' do
65
+
66
+ before :each do
67
+ account = {
68
+ :folders => [{:name => 'my_folder'}]
69
+ }
70
+ folder1 = stub('folder', :name => 'my_folder') # this one is already backed up
71
+ folder2 = stub('folder', :name => 'another_folder')
72
+ remote_folders = [folder1, folder2]
73
+ @connection = setup_account(account, remote_folders)
74
+ end
75
+
76
+ it 'should list folders' do
77
+ subject.run
78
+
79
+ @output.string.should =~ /my_folder/
80
+ end
81
+
82
+ it 'should show which folders are already being backed up' do
83
+ subject.run
84
+
85
+ @output.string.should =~ /\d+\. \+ my_folder/
86
+ @output.string.should =~ /\d+\. \- another_folder/
87
+ end
88
+
89
+ it 'should add folders' do
90
+ state = :initial
91
+ @input.stub(:gets) do
92
+ case state
93
+ when :initial
94
+ state = :added
95
+ "2\n" # choose 'another_folder'
96
+ else
97
+ "q\n"
98
+ end
99
+ end
100
+
101
+ subject.run
102
+
103
+ @output.string.should =~ /\d+\. \+ another_folder/
104
+ @account[:folders].should include( { :name => 'another_folder' } )
105
+ end
106
+
107
+ it 'should remove folders' do
108
+ state = :initial
109
+ @input.stub(:gets) do
110
+ case state
111
+ when :initial
112
+ state = :added
113
+ "1\n"
114
+ else
115
+ "q\n"
116
+ end
117
+ end
118
+
119
+ subject.run
120
+
121
+ @output.string.should =~ /\d+\. \- my_folder/
122
+ @account[:folders].should_not include( { :name => 'my_folder' } )
123
+ end
124
+
125
+
126
+ end
127
+
128
+ end
129
+
130
+ end
131
+
@@ -0,0 +1,73 @@
1
+ # encoding: utf-8
2
+ load File.expand_path( '../../spec_helper.rb', File.dirname(__FILE__) )
3
+
4
+ describe Imap::Backup::Configuration::List do
5
+ before :each do
6
+ @configuration_data = {
7
+ :accounts => [
8
+ {
9
+ :username => 'a1@example.com'
10
+ },
11
+ {
12
+ :username => 'a2@example.com',
13
+ },
14
+ ]
15
+ }
16
+ @store = stub('Imap::Backup::Configuration::Store', :data => @configuration_data)
17
+ Imap::Backup::Configuration::Store.stub!(:new => @store)
18
+ end
19
+
20
+ context '#initialize' do
21
+
22
+ context 'with account parameter' do
23
+ it 'should only create requested accounts' do
24
+ configuration = Imap::Backup::Configuration::List.new(['a2@example.com'])
25
+
26
+ configuration.accounts.should == @configuration_data[:accounts][1..1]
27
+ end
28
+ end
29
+
30
+ end
31
+
32
+ context 'instance methods' do
33
+
34
+ before :each do
35
+ @connection = stub('Imap::Backup::Account::Connection', :disconnect => nil)
36
+ end
37
+
38
+ subject { Imap::Backup::Configuration::List.new }
39
+
40
+ context '#each_connection' do
41
+
42
+ it 'should instantiate connections' do
43
+ Imap::Backup::Account::Connection.should_receive(:new).with(@configuration_data[:accounts][0]).and_return(@connection)
44
+ Imap::Backup::Account::Connection.should_receive(:new).with(@configuration_data[:accounts][1]).and_return(@connection)
45
+
46
+ subject.each_connection{}
47
+ end
48
+
49
+ it 'should call the block' do
50
+ Imap::Backup::Account::Connection.stub!(:new).and_return(@connection)
51
+ calls = 0
52
+
53
+ subject.each_connection do |a|
54
+ calls += 1
55
+ a.should == @connection
56
+ end
57
+ calls.should == 2
58
+ end
59
+
60
+ it 'should disconnect connections' do
61
+ Imap::Backup::Account::Connection.stub!(:new).and_return(@connection)
62
+
63
+ @connection.should_receive(:disconnect)
64
+
65
+ subject.each_connection {}
66
+ end
67
+
68
+ end
69
+
70
+ end
71
+
72
+ end
73
+
@@ -0,0 +1,115 @@
1
+ # encoding: utf-8
2
+ load File.expand_path( '../../spec_helper.rb', File.dirname(__FILE__) )
3
+
4
+ describe Imap::Backup::Configuration::Setup do
5
+
6
+ include HighLineTestHelpers
7
+
8
+ context '#initialize' do
9
+
10
+ it 'should not require the config file to exist' do
11
+ Imap::Backup::Configuration::Store.should_receive(:new).with(false)
12
+
13
+ Imap::Backup::Configuration::Setup.new
14
+ end
15
+
16
+ end
17
+
18
+ context '#run' do
19
+
20
+ before :each do
21
+ prepare_store
22
+ @input, @output = prepare_highline
23
+ end
24
+
25
+ def prepare_store
26
+ accounts = [
27
+ { :username => 'account@example.com' }
28
+ ]
29
+ @data = {:accounts => accounts}
30
+ @store = stub('Imap::Backup::Configuration::Store', :data => @data, :path => '/base/path')
31
+ Imap::Backup::Configuration::Store.stub!(:new).with(false).and_return(@store)
32
+ end
33
+
34
+ subject { Imap::Backup::Configuration::Setup.new }
35
+
36
+ it 'should present a main menu' do
37
+ @input.should_receive(:eof?).and_return(false)
38
+ @input.should_receive(:gets).and_return("q\n")
39
+
40
+ subject.run
41
+
42
+ @output.string.should =~ /Choose an action:/
43
+ @output.string.should =~ /add account/
44
+ @output.string.should =~ /save and exit/
45
+ @output.string.should =~ /quit/
46
+ end
47
+
48
+ it 'should list accounts' do
49
+ subject.run
50
+
51
+ @output.string.should =~ /account@example.com/
52
+ end
53
+
54
+ it 'should edit accounts' do
55
+ state = :initial
56
+ @input.stub(:gets) do
57
+ case state
58
+ when :initial
59
+ state = :editing
60
+ "account@example.com\n"
61
+ else
62
+ "q\n"
63
+ end
64
+ end
65
+
66
+ @account = stub('Imap::Backup::Configuration::Account')
67
+ Imap::Backup::Configuration::Account.should_receive(:new).with(@store, 'account@example.com').and_return(@account)
68
+ @account.should_receive(:run).with()
69
+
70
+ subject.run
71
+ end
72
+
73
+ it 'should add accounts' do
74
+ state = :initial
75
+ @input.stub(:gets) do
76
+ case state
77
+ when :initial
78
+ state = :editing
79
+ "add\n"
80
+ else
81
+ "q\n"
82
+ end
83
+ end
84
+
85
+ Imap::Backup::Configuration::Asker.should_receive(:email).with().and_return('new@example.com')
86
+ Imap::Backup::Configuration::Account.should_receive(:new).with(@store, 'new@example.com')
87
+
88
+ subject.run
89
+
90
+ @data[:accounts].size.should == 2
91
+ @data[:accounts][1].should == {
92
+ :username => "new@example.com",
93
+ :password => "",
94
+ :local_path => "/base/path/new_example.com",
95
+ :folders => []
96
+ }
97
+ end
98
+
99
+ it 'should save the configuration' do
100
+ @input.should_receive(:gets).with().and_return("save\n")
101
+ @store.should_receive(:save).with()
102
+
103
+ subject.run
104
+ end
105
+
106
+ it 'should exit' do
107
+ @input.should_receive(:gets).with().and_return("quit\n")
108
+
109
+ subject.run
110
+ end
111
+
112
+ end
113
+
114
+ end
115
+
@@ -0,0 +1,173 @@
1
+ # encoding: utf-8
2
+ load File.expand_path( '../../spec_helper.rb', File.dirname(__FILE__) )
3
+
4
+ describe Imap::Backup::Configuration::Store do
5
+
6
+ before :all do
7
+ @configuration_directory = Imap::Backup::Configuration::Store::CONFIGURATION_DIRECTORY
8
+ Imap::Backup::Configuration::Store.instance_eval { remove_const :'CONFIGURATION_DIRECTORY' }
9
+ Imap::Backup::Configuration::Store::CONFIGURATION_DIRECTORY = '/base/path'
10
+ end
11
+
12
+ after :all do
13
+ Imap::Backup::Configuration::Store.instance_eval { remove_const :'CONFIGURATION_DIRECTORY' }
14
+ Imap::Backup::Configuration::Store::CONFIGURATION_DIRECTORY = @configuration_directory
15
+ end
16
+
17
+ context '#initialize' do
18
+
19
+ before :each do
20
+ Imap::Backup::Utils.stub!(:check_permissions => nil)
21
+ end
22
+
23
+ it 'by default, should fail if the config file is missing' do
24
+ File.should_receive(:directory?).with('/base/path').and_return(true)
25
+ File.should_receive(:exist?).with('/base/path/config.json').and_return(false)
26
+
27
+ expect do
28
+ Imap::Backup::Configuration::Store.new
29
+ end.to raise_error(Imap::Backup::ConfigurationNotFound, /not found/)
30
+ end
31
+
32
+ it 'should not fail if fail_if_missing is false' do
33
+ File.should_receive(:directory?).with('/base/path').and_return(true)
34
+ File.should_receive(:exist?).with('/base/path/config.json').and_return(false)
35
+
36
+ expect do
37
+ Imap::Backup::Configuration::Store.new(false)
38
+ end.to_not raise_error
39
+ end
40
+
41
+ it 'should fail if the config file permissions are too lax' do
42
+ File.stub!(:exist?).with('/base/path/config.json').and_return(true)
43
+
44
+ Imap::Backup::Utils.should_receive(:check_permissions).with('/base/path/config.json', 0600).and_raise('Error')
45
+
46
+ expect do
47
+ Imap::Backup::Configuration::Store.new
48
+ end.to raise_error(RuntimeError, 'Error')
49
+ end
50
+
51
+ it 'should load the config file' do
52
+ File.stub!(:exist?).with('/base/path/config.json').and_return(true)
53
+
54
+ configuration = 'JSON string'
55
+ File.should_receive(:read).with('/base/path/config.json').and_return(configuration)
56
+ JSON.should_receive(:parse).with(configuration, :symbolize_names => true)
57
+
58
+ Imap::Backup::Configuration::Store.new
59
+ end
60
+
61
+ end
62
+
63
+ context '#save' do
64
+
65
+ before :each do
66
+ # initialize
67
+ File.stub!(:directory?).with('/base/path').and_return(false)
68
+ File.stub!(:exist?).with('/base/path/config.json').and_return(false)
69
+ # save
70
+ @file = stub('File')
71
+ File.stub!(:directory?).with('/base/path').and_return(false)
72
+ FileUtils.stub!(:mkdir).with('/base/path')
73
+ Imap::Backup::Utils.stub!(:stat).with('/base/path').and_return(0700)
74
+ FileUtils.stub!(:chmod).with(0700, '/base/path')
75
+ File.stub!(:open).with('/base/path/config.json', 'w') { |&b| b.call @file }
76
+ JSON.stub!(:pretty_generate => 'JSON output')
77
+ @file.stub!(:write).with('JSON output')
78
+ FileUtils.stub!(:chmod).with(0600, '/base/path/config.json')
79
+ end
80
+
81
+ subject { Imap::Backup::Configuration::Store.new(false) }
82
+
83
+ it 'should create the config directory' do
84
+ File.should_receive(:directory?).with('/base/path').and_return(false)
85
+ FileUtils.should_receive(:mkdir).with('/base/path')
86
+
87
+ subject.save
88
+ end
89
+
90
+ it 'should save the config file' do
91
+ @file.should_receive(:write).with('JSON output')
92
+
93
+ subject.save
94
+ end
95
+
96
+ it 'should set config perms to 0600' do
97
+ FileUtils.should_receive(:chmod).with(0600, '/base/path/config.json')
98
+
99
+ subject.save
100
+ end
101
+
102
+ context 'saving accounts' do
103
+
104
+ before :each do
105
+ # initialize
106
+ File.stub!(:exist?).with('/base/path/config.json').and_return(true)
107
+ Imap::Backup::Utils.stub!(:check_permissions).with('/base/path/config.json', 0600)
108
+ folders = [
109
+ { :name => 'A folder' },
110
+ ]
111
+ File.stub!(:read).with('/base/path/config.json').and_return('xxx')
112
+ JSON.stub!(:parse).with('xxx', :symbolize_names => true).and_return(configuration(folders))
113
+ # save
114
+ File.stub!(:directory?).with('/my/backup/path').and_return(false)
115
+ FileUtils.stub!(:mkdir).with('/my/backup/path')
116
+ Imap::Backup::Utils.stub!(:stat).with('/my/backup/path').and_return(0700)
117
+ File.stub!(:directory?).with('/my/backup/path/A folder').and_return(false)
118
+ FileUtils.stub!(:mkdir).with('/my/backup/path/A folder')
119
+ Imap::Backup::Utils.stub!(:stat).with('/my/backup/path/A folder').and_return(0700)
120
+ end
121
+
122
+ def configuration(folders)
123
+ {
124
+ :accounts => [
125
+ :local_path => '/my/backup/path',
126
+ :folders => folders
127
+ ]
128
+ }
129
+ end
130
+
131
+ subject { Imap::Backup::Configuration::Store.new }
132
+
133
+ it 'should create account directories' do
134
+ File.should_receive(:directory?).with('/my/backup/path').and_return(false)
135
+ FileUtils.should_receive(:mkdir).with('/my/backup/path')
136
+
137
+ subject.save
138
+ end
139
+
140
+ it 'should create folder directories' do
141
+ File.should_receive(:directory?).with('/my/backup/path/A folder').and_return(false)
142
+ FileUtils.should_receive(:mkdir).with('/my/backup/path/A folder')
143
+
144
+ subject.save
145
+ end
146
+
147
+ it 'should set directory permissions, if necessary' do
148
+ Imap::Backup::Utils.stub!(:stat).with('/my/backup/path/A folder').and_return(0755)
149
+ FileUtils.should_receive(:chmod).with(0700, '/my/backup/path/A folder')
150
+
151
+ subject.save
152
+ end
153
+
154
+ it 'should create a path for folders with slashes' do
155
+ folders = [
156
+ { :name => 'folder/path' },
157
+ ]
158
+ JSON.stub!(:parse).with('xxx', :symbolize_names => true).and_return(configuration(folders))
159
+
160
+ File.should_receive(:directory?).with('/my/backup/path/folder').and_return(true)
161
+ Imap::Backup::Utils.should_receive(:stat).with('/my/backup/path/folder').and_return(0700)
162
+ File.should_receive(:directory?).with('/my/backup/path/folder/path').and_return(true)
163
+ Imap::Backup::Utils.should_receive(:stat).with('/my/backup/path/folder/path').and_return(0700)
164
+
165
+ subject.save
166
+ end
167
+
168
+ end
169
+
170
+ end
171
+
172
+ end
173
+