backup 3.0.20 → 3.0.21

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.
Files changed (178) hide show
  1. data/Gemfile +1 -5
  2. data/Gemfile.lock +46 -50
  3. data/README.md +54 -27
  4. data/lib/backup.rb +16 -39
  5. data/lib/backup/archive.rb +42 -18
  6. data/lib/backup/cleaner.rb +110 -25
  7. data/lib/backup/cli/helpers.rb +17 -32
  8. data/lib/backup/cli/utility.rb +46 -107
  9. data/lib/backup/compressor/base.rb +14 -2
  10. data/lib/backup/compressor/bzip2.rb +10 -24
  11. data/lib/backup/compressor/gzip.rb +10 -24
  12. data/lib/backup/compressor/lzma.rb +10 -23
  13. data/lib/backup/compressor/pbzip2.rb +12 -32
  14. data/lib/backup/config.rb +171 -0
  15. data/lib/backup/configuration/compressor/base.rb +1 -2
  16. data/lib/backup/configuration/compressor/pbzip2.rb +4 -4
  17. data/lib/backup/configuration/database/base.rb +2 -1
  18. data/lib/backup/configuration/database/mongodb.rb +8 -0
  19. data/lib/backup/configuration/database/mysql.rb +4 -0
  20. data/lib/backup/configuration/database/postgresql.rb +4 -0
  21. data/lib/backup/configuration/database/redis.rb +4 -0
  22. data/lib/backup/configuration/database/riak.rb +5 -1
  23. data/lib/backup/configuration/encryptor/base.rb +1 -2
  24. data/lib/backup/configuration/encryptor/open_ssl.rb +1 -1
  25. data/lib/backup/configuration/helpers.rb +7 -2
  26. data/lib/backup/configuration/notifier/base.rb +4 -28
  27. data/lib/backup/configuration/storage/base.rb +1 -1
  28. data/lib/backup/configuration/storage/dropbox.rb +14 -4
  29. data/lib/backup/configuration/syncer/base.rb +10 -0
  30. data/lib/backup/configuration/syncer/rsync/base.rb +28 -0
  31. data/lib/backup/configuration/syncer/rsync/local.rb +11 -0
  32. data/lib/backup/configuration/syncer/rsync/pull.rb +11 -0
  33. data/lib/backup/configuration/syncer/rsync/push.rb +31 -0
  34. data/lib/backup/configuration/syncer/s3.rb +0 -4
  35. data/lib/backup/database/base.rb +25 -7
  36. data/lib/backup/database/mongodb.rb +112 -75
  37. data/lib/backup/database/mysql.rb +54 -29
  38. data/lib/backup/database/postgresql.rb +60 -42
  39. data/lib/backup/database/redis.rb +61 -39
  40. data/lib/backup/database/riak.rb +35 -11
  41. data/lib/backup/dependency.rb +4 -5
  42. data/lib/backup/encryptor/base.rb +13 -1
  43. data/lib/backup/encryptor/gpg.rb +39 -39
  44. data/lib/backup/encryptor/open_ssl.rb +28 -38
  45. data/lib/backup/logger.rb +20 -11
  46. data/lib/backup/model.rb +206 -163
  47. data/lib/backup/notifier/base.rb +27 -25
  48. data/lib/backup/notifier/campfire.rb +7 -13
  49. data/lib/backup/notifier/hipchat.rb +28 -28
  50. data/lib/backup/notifier/mail.rb +24 -26
  51. data/lib/backup/notifier/presently.rb +10 -18
  52. data/lib/backup/notifier/prowl.rb +9 -17
  53. data/lib/backup/notifier/twitter.rb +11 -18
  54. data/lib/backup/package.rb +47 -0
  55. data/lib/backup/packager.rb +81 -16
  56. data/lib/backup/splitter.rb +48 -35
  57. data/lib/backup/storage/base.rb +44 -172
  58. data/lib/backup/storage/cloudfiles.rb +31 -46
  59. data/lib/backup/storage/cycler.rb +117 -0
  60. data/lib/backup/storage/dropbox.rb +92 -76
  61. data/lib/backup/storage/ftp.rb +30 -40
  62. data/lib/backup/storage/local.rb +44 -45
  63. data/lib/backup/storage/ninefold.rb +55 -49
  64. data/lib/backup/storage/rsync.rb +49 -56
  65. data/lib/backup/storage/s3.rb +33 -44
  66. data/lib/backup/storage/scp.rb +21 -48
  67. data/lib/backup/storage/sftp.rb +26 -40
  68. data/lib/backup/syncer/base.rb +7 -0
  69. data/lib/backup/syncer/rsync/base.rb +78 -0
  70. data/lib/backup/syncer/rsync/local.rb +53 -0
  71. data/lib/backup/syncer/rsync/pull.rb +38 -0
  72. data/lib/backup/syncer/rsync/push.rb +113 -0
  73. data/lib/backup/syncer/s3.rb +42 -32
  74. data/lib/backup/version.rb +1 -1
  75. data/spec/archive_spec.rb +235 -69
  76. data/spec/cleaner_spec.rb +304 -0
  77. data/spec/cli/helpers_spec.rb +142 -1
  78. data/spec/cli/utility_spec.rb +338 -13
  79. data/spec/compressor/base_spec.rb +31 -0
  80. data/spec/compressor/bzip2_spec.rb +60 -35
  81. data/spec/compressor/gzip_spec.rb +60 -35
  82. data/spec/compressor/lzma_spec.rb +60 -35
  83. data/spec/compressor/pbzip2_spec.rb +98 -37
  84. data/spec/config_spec.rb +321 -0
  85. data/spec/configuration/base_spec.rb +4 -4
  86. data/spec/configuration/compressor/bzip2_spec.rb +1 -0
  87. data/spec/configuration/compressor/gzip_spec.rb +1 -0
  88. data/spec/configuration/compressor/lzma_spec.rb +1 -0
  89. data/spec/configuration/compressor/pbzip2_spec.rb +32 -0
  90. data/spec/configuration/database/base_spec.rb +2 -1
  91. data/spec/configuration/database/mongodb_spec.rb +26 -16
  92. data/spec/configuration/database/mysql_spec.rb +4 -0
  93. data/spec/configuration/database/postgresql_spec.rb +4 -0
  94. data/spec/configuration/database/redis_spec.rb +4 -0
  95. data/spec/configuration/database/riak_spec.rb +4 -0
  96. data/spec/configuration/encryptor/gpg_spec.rb +1 -0
  97. data/spec/configuration/encryptor/open_ssl_spec.rb +1 -0
  98. data/spec/configuration/notifier/base_spec.rb +32 -0
  99. data/spec/configuration/notifier/campfire_spec.rb +1 -0
  100. data/spec/configuration/notifier/hipchat_spec.rb +1 -0
  101. data/spec/configuration/notifier/mail_spec.rb +1 -0
  102. data/spec/configuration/notifier/presently_spec.rb +1 -0
  103. data/spec/configuration/notifier/prowl_spec.rb +1 -0
  104. data/spec/configuration/notifier/twitter_spec.rb +1 -0
  105. data/spec/configuration/storage/cloudfiles_spec.rb +1 -0
  106. data/spec/configuration/storage/dropbox_spec.rb +4 -3
  107. data/spec/configuration/storage/ftp_spec.rb +1 -0
  108. data/spec/configuration/storage/local_spec.rb +1 -0
  109. data/spec/configuration/storage/ninefold_spec.rb +1 -0
  110. data/spec/configuration/storage/rsync_spec.rb +3 -1
  111. data/spec/configuration/storage/s3_spec.rb +1 -0
  112. data/spec/configuration/storage/scp_spec.rb +1 -0
  113. data/spec/configuration/storage/sftp_spec.rb +1 -0
  114. data/spec/configuration/syncer/rsync/base_spec.rb +33 -0
  115. data/spec/configuration/syncer/rsync/local_spec.rb +10 -0
  116. data/spec/configuration/syncer/rsync/pull_spec.rb +10 -0
  117. data/spec/configuration/syncer/{rsync_spec.rb → rsync/push_spec.rb} +12 -15
  118. data/spec/configuration/syncer/s3_spec.rb +2 -3
  119. data/spec/database/base_spec.rb +35 -20
  120. data/spec/database/mongodb_spec.rb +298 -119
  121. data/spec/database/mysql_spec.rb +147 -72
  122. data/spec/database/postgresql_spec.rb +155 -100
  123. data/spec/database/redis_spec.rb +200 -97
  124. data/spec/database/riak_spec.rb +82 -24
  125. data/spec/dependency_spec.rb +49 -0
  126. data/spec/encryptor/base_spec.rb +30 -0
  127. data/spec/encryptor/gpg_spec.rb +105 -28
  128. data/spec/encryptor/open_ssl_spec.rb +85 -114
  129. data/spec/logger_spec.rb +74 -8
  130. data/spec/model_spec.rb +528 -220
  131. data/spec/notifier/base_spec.rb +89 -0
  132. data/spec/notifier/campfire_spec.rb +147 -119
  133. data/spec/notifier/hipchat_spec.rb +140 -145
  134. data/spec/notifier/mail_spec.rb +190 -248
  135. data/spec/notifier/presently_spec.rb +147 -282
  136. data/spec/notifier/prowl_spec.rb +79 -111
  137. data/spec/notifier/twitter_spec.rb +87 -106
  138. data/spec/package_spec.rb +61 -0
  139. data/spec/packager_spec.rb +154 -0
  140. data/spec/spec_helper.rb +36 -13
  141. data/spec/splitter_spec.rb +90 -41
  142. data/spec/storage/base_spec.rb +95 -239
  143. data/spec/storage/cloudfiles_spec.rb +185 -75
  144. data/spec/storage/cycler_spec.rb +239 -0
  145. data/spec/storage/dropbox_spec.rb +318 -87
  146. data/spec/storage/ftp_spec.rb +165 -152
  147. data/spec/storage/local_spec.rb +206 -54
  148. data/spec/storage/ninefold_spec.rb +264 -128
  149. data/spec/storage/rsync_spec.rb +244 -163
  150. data/spec/storage/s3_spec.rb +175 -64
  151. data/spec/storage/scp_spec.rb +156 -150
  152. data/spec/storage/sftp_spec.rb +153 -135
  153. data/spec/syncer/base_spec.rb +22 -0
  154. data/spec/syncer/rsync/base_spec.rb +118 -0
  155. data/spec/syncer/rsync/local_spec.rb +121 -0
  156. data/spec/syncer/rsync/pull_spec.rb +90 -0
  157. data/spec/syncer/rsync/push_spec.rb +327 -0
  158. data/spec/syncer/s3_spec.rb +180 -91
  159. data/templates/cli/utility/config +1 -1
  160. data/templates/cli/utility/database/mongodb +4 -0
  161. data/templates/cli/utility/database/mysql +3 -0
  162. data/templates/cli/utility/database/postgresql +3 -0
  163. data/templates/cli/utility/database/redis +3 -0
  164. data/templates/cli/utility/database/riak +3 -0
  165. data/templates/cli/utility/storage/dropbox +4 -1
  166. data/templates/cli/utility/syncer/rsync_local +12 -0
  167. data/templates/cli/utility/syncer/{rsync → rsync_pull} +2 -2
  168. data/templates/cli/utility/syncer/rsync_push +17 -0
  169. data/templates/storage/dropbox/authorization_url.erb +1 -1
  170. metadata +42 -17
  171. data/lib/backup/configuration/syncer/rsync.rb +0 -45
  172. data/lib/backup/finder.rb +0 -87
  173. data/lib/backup/storage/object.rb +0 -47
  174. data/lib/backup/syncer/rsync.rb +0 -152
  175. data/spec/backup_spec.rb +0 -11
  176. data/spec/finder_spec.rb +0 -91
  177. data/spec/storage/object_spec.rb +0 -74
  178. data/spec/syncer/rsync_spec.rb +0 -195
@@ -3,136 +3,367 @@
3
3
  require File.expand_path('../../spec_helper.rb', __FILE__)
4
4
 
5
5
  describe Backup::Storage::Dropbox do
6
-
7
- let(:db) do
8
- Backup::Storage::Dropbox.new do |db|
9
- db.api_key = 'my_api_key'
10
- db.api_secret = 'my_secret'
11
- db.keep = 20
12
- db.timeout = 500
6
+ let(:model) { Backup::Model.new(:test_trigger, 'test label') }
7
+ let(:storage) do
8
+ Backup::Storage::Dropbox.new(model) do |db|
9
+ db.api_key = 'my_api_key'
10
+ db.api_secret = 'my_api_secret'
11
+ db.keep = 5
13
12
  end
14
13
  end
15
14
 
16
- let(:connection) do
17
- c = mock("Dropbox::Session")
18
- db.stubs(:connection).returns(c); c
19
- end
15
+ describe '#initialize' do
16
+ it 'should set the correct values' do
17
+ storage.api_key.should == 'my_api_key'
18
+ storage.api_secret.should == 'my_api_secret'
19
+ storage.access_type.should == :app_folder
20
+ storage.path.should == 'backups'
20
21
 
21
- before do
22
- Backup::Configuration::Storage::Dropbox.clear_defaults!
23
- STDIN.stubs(:gets)
24
- end
25
-
26
- it 'should have defined the configuration properly' do
27
- db.api_key.should == 'my_api_key'
28
- db.api_secret.should == 'my_secret'
29
- db.path.should == 'backups'
30
- db.keep.should == 20
31
- db.timeout.should == 500
32
- end
22
+ storage.storage_id.should be_nil
23
+ storage.keep.should == 5
24
+ end
33
25
 
34
- it 'should overwrite the default timeout' do
35
- db = Backup::Storage::Dropbox.new do |db|
36
- db.timeout = 500
26
+ it 'should set a storage_id if given' do
27
+ db = Backup::Storage::Dropbox.new(model, 'my storage_id')
28
+ db.storage_id.should == 'my storage_id'
37
29
  end
38
30
 
39
- db.timeout.should == 500
40
- end
31
+ context 'when setting configuration defaults' do
32
+ after { Backup::Configuration::Storage::Dropbox.clear_defaults! }
41
33
 
42
- it 'should provide a default timeout' do
43
- db = Backup::Storage::Dropbox.new
34
+ it 'should use the configured defaults' do
35
+ Backup::Configuration::Storage::Dropbox.defaults do |db|
36
+ db.api_key = 'some_api_key'
37
+ db.api_secret = 'some_api_secret'
38
+ db.access_type = 'some_access_type'
39
+ db.path = 'some_path'
40
+ db.keep = 15
41
+ end
42
+ storage = Backup::Storage::Dropbox.new(model)
43
+ storage.api_key.should == 'some_api_key'
44
+ storage.api_secret.should == 'some_api_secret'
45
+ storage.access_type.should == 'some_access_type'
46
+ storage.path.should == 'some_path'
44
47
 
45
- db.timeout.should == 300
46
- end
48
+ storage.storage_id.should be_nil
49
+ storage.keep.should == 15
50
+ end
47
51
 
48
- it 'should overwrite the default path' do
49
- db = Backup::Storage::Dropbox.new do |db|
50
- db.path = 'my/backups'
51
- end
52
+ it 'should override the configured defaults' do
53
+ Backup::Configuration::Storage::Dropbox.defaults do |db|
54
+ db.api_key = 'old_api_key'
55
+ db.api_secret = 'old_api_secret'
56
+ db.access_type = 'old_access_type'
57
+ db.path = 'old_path'
58
+ db.keep = 15
59
+ end
60
+ storage = Backup::Storage::Dropbox.new(model) do |db|
61
+ db.api_key = 'new_api_key'
62
+ db.api_secret = 'new_api_secret'
63
+ db.access_type = 'new_access_type'
64
+ db.path = 'new_path'
65
+ db.keep = 10
66
+ end
52
67
 
53
- db.path.should == 'my/backups'
54
- end
68
+ storage.api_key.should == 'new_api_key'
69
+ storage.api_secret.should == 'new_api_secret'
70
+ storage.access_type.should == 'new_access_type'
71
+ storage.path.should == 'new_path'
72
+
73
+ storage.storage_id.should be_nil
74
+ storage.keep.should == 10
75
+ end
76
+ end # context 'when setting configuration defaults'
77
+
78
+ end # describe '#initialize'
55
79
 
56
80
  describe '#connection' do
57
- before do
58
- db.stubs(:gets)
81
+ let(:session) { mock }
82
+ let(:client) { mock }
83
+ let(:s) { sequence '' }
84
+
85
+ context 'when a cached session exists' do
86
+ before do
87
+ storage.expects(:cached_session).in_sequence(s).returns(session)
88
+ storage.expects(:create_write_and_return_new_session!).never
89
+ DropboxClient.expects(:new).in_sequence(s).
90
+ with(session, :app_folder).returns(client)
91
+ end
92
+
93
+ it 'should use the cached session to create the client' do
94
+ storage.send(:connection).should be(client)
95
+ end
96
+
97
+ it 'should return an already existing client' do
98
+ storage.send(:connection).should be(client)
99
+ storage.send(:connection).should be(client)
100
+ end
59
101
  end
60
102
 
61
- context "when the session cache has not yet been written" do
62
- it do
63
- session = mock("Dropbox::Session")
64
- Dropbox::Session.expects(:new).with('my_api_key', 'my_secret').returns(session)
65
- session.expects(:mode=).with(:dropbox)
66
- session.expects(:authorize)
67
- db.expects(:cache_exists?).returns(false)
68
- db.expects(:write_cache!).with(session)
103
+ context 'when a cached session does not exist' do
104
+ before do
105
+ storage.expects(:cached_session).in_sequence(s).returns(false)
106
+ Backup::Logger.expects(:message).in_sequence(s).with(
107
+ 'Creating a new session!'
108
+ )
109
+ storage.expects(:create_write_and_return_new_session!).in_sequence(s).
110
+ returns(session)
111
+ DropboxClient.expects(:new).in_sequence(s).
112
+ with(session, :app_folder).returns(client)
113
+ end
69
114
 
70
- template = Backup::Template.new(db.send(:binding))
71
- Backup::Template.expects(:new).returns(template)
115
+ it 'should create a new session and return the client' do
116
+ storage.send(:connection).should be(client)
117
+ end
72
118
 
73
- template.expects(:render).times(3)
74
- db.send(:connection)
119
+ it 'should return an already existing client' do
120
+ storage.send(:connection).should be(client)
121
+ storage.send(:connection).should be(client)
75
122
  end
76
123
  end
77
124
 
78
- context "when the session cache has already been written" do
79
- it "should load the session from cache, instead of creating a new one" do
80
- db.expects(:cache_exists?).returns(true)
81
- File.expects(:read).with("#{ENV['HOME']}/Backup/.cache/my_api_keymy_secret").returns("foo")
82
- session = mock("Dropbox::Session")
83
- session.expects(:authorized?).returns(true)
84
- Dropbox::Session.expects(:deserialize).with("foo").returns(session)
125
+ context 'when an error is raised creating a client for the session' do
126
+ it 'should wrap and raise the error' do
127
+ storage.stubs(:cached_session).returns(true)
128
+ DropboxClient.expects(:new).raises('error')
129
+
130
+ expect do
131
+ storage.send(:connection)
132
+ end.to raise_error {|err|
133
+ err.should be_an_instance_of(
134
+ Backup::Errors::Storage::Dropbox::ConnectionError
135
+ )
136
+ err.message.should ==
137
+ 'Storage::Dropbox::ConnectionError: RuntimeError: error'
138
+ }
139
+ end
140
+ end
141
+
142
+ end # describe '#connection'
143
+
144
+ describe '#cached_session' do
145
+ let(:session) { mock }
85
146
 
86
- db.expects(:create_write_and_return_new_session!).never
87
- db.send(:connection)
147
+ context 'when a cached session file exists' do
148
+ before do
149
+ storage.expects(:cache_exists?).returns(true)
150
+ storage.expects(:cached_file).returns('cached_file')
151
+ File.expects(:read).with('cached_file').returns('yaml_data')
88
152
  end
89
153
 
90
- it "should load it from cache, but if it's invalid/corrupt, the create a session anyway" do
91
- db.expects(:cache_exists?).returns(true)
92
- File.expects(:read).with("#{ENV['HOME']}/Backup/.cache/my_api_keymy_secret").returns("foo")
93
- session = mock("Dropbox::Session")
94
- session.expects(:authorized?).returns(false)
95
- Dropbox::Session.expects(:deserialize).with("foo").returns(session)
154
+ context 'when the cached session is successfully loaded' do
155
+ it 'should return the sesssion' do
156
+ DropboxSession.expects(:deserialize).with('yaml_data').
157
+ returns(session)
158
+ Backup::Logger.expects(:message).with(
159
+ 'Session data loaded from cache!'
160
+ )
96
161
 
97
- db.expects(:create_write_and_return_new_session!)
98
- db.send(:connection)
162
+ storage.send(:cached_session).should be(session)
163
+ end
164
+ end
165
+
166
+ context 'when errors occur loading the session' do
167
+ it 'should log a warning and return false' do
168
+ DropboxSession.expects(:deserialize).with('yaml_data').
169
+ raises('error message')
170
+ Backup::Logger.expects(:warn).with do |err|
171
+ err.should be_an_instance_of(
172
+ Backup::Errors::Storage::Dropbox::CacheError
173
+ )
174
+ err.message.should == 'Storage::Dropbox::CacheError: ' +
175
+ "Could not read session data from cache.\n" +
176
+ " Cache data might be corrupt.\n" +
177
+ " Reason: RuntimeError\n" +
178
+ " error message"
179
+ end
180
+
181
+ expect do
182
+ storage.send(:cached_session).should be_false
183
+ end.not_to raise_error
184
+ end
185
+ end
186
+ end
187
+
188
+ context 'when a cached session file does not exist' do
189
+ before { storage.stubs(:cache_exists?).returns(false) }
190
+ it 'should return false' do
191
+ storage.send(:cached_session).should be_false
99
192
  end
100
193
  end
101
194
  end
102
195
 
103
196
  describe '#transfer!' do
197
+ let(:connection) { mock }
198
+ let(:package) { mock }
199
+ let(:file) { mock }
200
+ let(:s) { sequence '' }
201
+
104
202
  before do
105
- connection.stubs(:upload)
106
- connection.stubs(:delete)
203
+ storage.instance_variable_set(:@package, package)
204
+ storage.stubs(:storage_name).returns('Storage::Dropbox')
205
+ storage.stubs(:local_path).returns('/local/path')
206
+ storage.stubs(:connection).returns(connection)
107
207
  end
108
208
 
109
- it do
110
- Backup::Logger.expects(:message).with(
209
+ it 'should transfer the package files' do
210
+ storage.expects(:remote_path_for).in_sequence(s).with(package).
211
+ returns('remote/path')
212
+ storage.expects(:files_to_transfer_for).in_sequence(s).with(package).
213
+ multiple_yields(
214
+ ['2011.12.31.11.00.02.backup.tar.enc-aa', 'backup.tar.enc-aa'],
215
+ ['2011.12.31.11.00.02.backup.tar.enc-ab', 'backup.tar.enc-ab']
216
+ )
217
+ # first yield
218
+ Backup::Logger.expects(:message).in_sequence(s).with(
219
+ "Storage::Dropbox started transferring " +
220
+ "'2011.12.31.11.00.02.backup.tar.enc-aa'."
221
+ )
222
+ File.expects(:open).in_sequence(s).with(
223
+ File.join('/local/path', '2011.12.31.11.00.02.backup.tar.enc-aa'), 'r'
224
+ ).yields(file)
225
+ connection.expects(:put_file).in_sequence(s).with(
226
+ File.join('remote/path', 'backup.tar.enc-aa'), file
227
+ )
228
+ # second yield
229
+ Backup::Logger.expects(:message).in_sequence(s).with(
111
230
  "Storage::Dropbox started transferring " +
112
- "'#{ Backup::TIME }.#{ Backup::TRIGGER }.tar'."
231
+ "'2011.12.31.11.00.02.backup.tar.enc-ab'."
232
+ )
233
+ File.expects(:open).in_sequence(s).with(
234
+ File.join('/local/path', '2011.12.31.11.00.02.backup.tar.enc-ab'), 'r'
235
+ ).yields(file)
236
+ connection.expects(:put_file).in_sequence(s).with(
237
+ File.join('remote/path', 'backup.tar.enc-ab'), file
113
238
  )
114
- db.send(:transfer!)
239
+
240
+ storage.send(:transfer!)
241
+ end
242
+ end # describe '#transfer!'
243
+
244
+ describe '#remove!' do
245
+ let(:package) { mock }
246
+ let(:connection) { mock }
247
+ let(:s) { sequence '' }
248
+
249
+ before do
250
+ storage.stubs(:storage_name).returns('Storage::Dropbox')
251
+ storage.stubs(:connection).returns(connection)
115
252
  end
116
253
 
117
- it do
118
- connection.expects(:upload).with(
119
- File.join(Backup::TMP_PATH, "#{ Backup::TIME }.#{ Backup::TRIGGER }.tar"),
120
- File.join('backups', Backup::TRIGGER, Backup::TIME),
121
- :as => "#{ Backup::TRIGGER }.tar",
122
- :timeout => db.timeout
254
+ it 'should remove the package files' do
255
+ storage.expects(:remote_path_for).in_sequence(s).with(package).
256
+ returns('remote/path')
257
+ storage.expects(:transferred_files_for).in_sequence(s).with(package).
258
+ multiple_yields(
259
+ ['2011.12.31.11.00.02.backup.tar.enc-aa', 'backup.tar.enc-aa'],
260
+ ['2011.12.31.11.00.02.backup.tar.enc-ab', 'backup.tar.enc-ab']
261
+ )
262
+ # after both yields
263
+ Backup::Logger.expects(:message).in_sequence(s).with(
264
+ "Storage::Dropbox started removing " +
265
+ "'2011.12.31.11.00.02.backup.tar.enc-aa' from Dropbox.\n" +
266
+ "Storage::Dropbox started removing " +
267
+ "'2011.12.31.11.00.02.backup.tar.enc-ab' from Dropbox."
123
268
  )
269
+ connection.expects(:file_delete).in_sequence(s).with('remote/path')
124
270
 
125
- db.send(:transfer!)
271
+ storage.send(:remove!, package)
272
+ end
273
+ end # describe '#remove!'
274
+
275
+ describe '#cached_file' do
276
+ it 'should return the path to the cache file' do
277
+ storage.send(:cached_file).should ==
278
+ File.join(Backup::Config.cache_path, 'my_api_keymy_api_secret')
126
279
  end
127
280
  end
128
281
 
129
- describe '#remove!' do
130
- it do
131
- connection.expects(:delete).with(
132
- File.join('backups', Backup::TRIGGER, Backup::TIME)
282
+ describe '#cache_exists?' do
283
+ it 'should check if #cached_file exists' do
284
+ storage.expects(:cached_file).returns('/path/to/cache_file')
285
+ File.expects(:exist?).with('/path/to/cache_file')
286
+
287
+ storage.send(:cache_exists?)
288
+ end
289
+ end
290
+
291
+ describe '#write_cache!' do
292
+ let(:session) { mock }
293
+ let(:cache_file) { mock }
294
+
295
+ it 'should write a serialized session to file' do
296
+ storage.expects(:cached_file).returns('/path/to/cache_file')
297
+ session.expects(:serialize).returns('serialized_data')
298
+
299
+ File.expects(:open).with('/path/to/cache_file', 'w').yields(cache_file)
300
+ cache_file.expects(:write).with('serialized_data')
301
+
302
+ storage.send(:write_cache!, session)
303
+ end
304
+ end
305
+
306
+ describe '#create_write_and_return_new_session!' do
307
+ let(:session) { mock }
308
+ let(:template) { mock }
309
+ let(:s) { sequence '' }
310
+
311
+ before do
312
+ storage.stubs(:cached_file).returns('/path/to/cache_file')
313
+
314
+ DropboxSession.expects(:new).in_sequence(s).
315
+ with('my_api_key', 'my_api_secret').returns(session)
316
+ session.expects(:get_request_token).in_sequence(s)
317
+ Backup::Template.expects(:new).in_sequence(s).with(
318
+ {:session => session, :cached_file => '/path/to/cache_file'}
319
+ ).returns(template)
320
+ template.expects(:render).in_sequence(s).with(
321
+ 'storage/dropbox/authorization_url.erb'
133
322
  )
323
+ Timeout.expects(:timeout).in_sequence(s).with(180).yields
324
+ STDIN.expects(:gets).in_sequence(s)
325
+ end
326
+
327
+ context 'when session is authenticated' do
328
+ before do
329
+ session.expects(:get_access_token).in_sequence(s)
330
+ end
331
+
332
+ it 'should cache and return the new session' do
333
+ template.expects(:render).in_sequence(s).with(
334
+ 'storage/dropbox/authorized.erb'
335
+ )
336
+ storage.expects(:write_cache!).in_sequence(s).with(session)
337
+ template.expects(:render).in_sequence(s).with(
338
+ 'storage/dropbox/cache_file_written.erb'
339
+ )
340
+
341
+ storage.send(:create_write_and_return_new_session!).should be(session)
342
+ end
343
+ end
134
344
 
135
- db.send(:remove!)
345
+ context 'when session is not authenticated' do
346
+ before do
347
+ session.expects(:get_access_token).in_sequence(s).raises('error message')
348
+ end
349
+
350
+ it 'should wrap and re-raise the error' do
351
+ template.expects(:render).with('storage/dropbox/authorized.erb').never
352
+ storage.expects(:write_cache!).never
353
+ template.expects(:render).with('storage/dropbox/cache_file_written.erb').never
354
+
355
+ expect do
356
+ storage.send(:create_write_and_return_new_session!)
357
+ end.to raise_error {|err|
358
+ err.should be_an_instance_of(
359
+ Backup::Errors::Storage::Dropbox::AuthenticationError
360
+ )
361
+ err.message.should == 'Storage::Dropbox::AuthenticationError: ' +
362
+ "Could not create or authenticate a new session\n" +
363
+ " Reason: RuntimeError\n" +
364
+ " error message"
365
+ }
366
+ end
136
367
  end
137
368
  end
138
369