rdropbox 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,144 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe Dropbox::Entry do
4
+ before :each do
5
+ @session = mock('Dropbox::Session')
6
+ @path = 'test/path/to/file'
7
+ @entry = Dropbox::Entry.new(@session, @path)
8
+ #TODO this constructor is opaque
9
+ end
10
+
11
+ describe "#metadata" do
12
+ it "should delegate to the session and return the result" do
13
+ result = mock('result')
14
+ @session.should_receive(:metadata).once.with(@path, {}).and_return(result)
15
+
16
+ @entry.metadata.should eql(result)
17
+ end
18
+
19
+ it "should pass along options" do
20
+ result = mock('result')
21
+ @session.should_receive(:metadata).once.with(@path, { :sandbox => true }).and_return(result)
22
+
23
+ @entry.metadata(:sandbox => true)
24
+ end
25
+ end
26
+
27
+ describe "#move" do
28
+ it "should delegate to the session and return the result" do
29
+ result = mock('result')
30
+ result.stub!(:path).and_return("newname")
31
+ @session.should_receive(:move).once.with(@path, 'new/path', {}).and_return(result)
32
+
33
+ @entry.move('new/path').should eql(result)
34
+ end
35
+
36
+ it "should pass along options" do
37
+ result = mock('result')
38
+ result.stub!(:path).and_return("newname")
39
+ @session.should_receive(:move).once.with(@path, 'new/path', { :sandbox => true }).and_return(result)
40
+
41
+ @entry.move('new/path', :sandbox => true)
42
+ end
43
+
44
+ it "should set the name according to the result" do
45
+ result = mock('result')
46
+ result.stub!(:path).and_return("resultname")
47
+ @session.should_receive(:move).once.with(@path, 'new/path', {}).and_return(result)
48
+
49
+ @entry.move('new/path')
50
+ @entry.path.should eql('resultname')
51
+ end
52
+ end
53
+
54
+ describe "#rename" do
55
+ it "should delegate to the session and return the result" do
56
+ result = mock('result')
57
+ result.stub!(:path).and_return("newname")
58
+ @session.should_receive(:rename).once.with(@path, 'newname', {}).and_return(result)
59
+
60
+ @entry.rename('newname').should eql(result)
61
+ end
62
+
63
+ it "should pass along options" do
64
+ result = mock('result')
65
+ result.stub!(:path).and_return("newname")
66
+ @session.should_receive(:rename).once.with(@path, 'newname', {}).and_return(result)
67
+
68
+ @entry.rename('newname')
69
+ end
70
+
71
+ it "should set the name according to the result" do
72
+ result = mock('result')
73
+ result.stub!(:path).and_return("resultname")
74
+ @session.should_receive(:rename).once.with(@path, 'newname', {}).and_return(result)
75
+
76
+ @entry.rename('newname')
77
+ @entry.path.should eql('resultname')
78
+ end
79
+ end
80
+
81
+ describe "#copy" do
82
+ it "should delegate to the session and return the result" do
83
+ result = mock('result')
84
+ @session.should_receive(:copy).once.with(@path, 'new/path', {}).and_return(result)
85
+
86
+ @entry.copy('new/path').should eql(result)
87
+ end
88
+
89
+ it "should pass along options" do
90
+ result = mock('result')
91
+ @session.should_receive(:copy).once.with(@path, 'new/path', { :sandbox => true }).and_return(result)
92
+
93
+ @entry.copy('new/path', :sandbox => true)
94
+ end
95
+ end
96
+
97
+ describe "#delete" do
98
+ it "should delegate to the session and return the result" do
99
+ result = mock('result')
100
+ @session.should_receive(:delete).once.with(@path, {}).and_return(result)
101
+
102
+ @entry.delete.should eql(result)
103
+ end
104
+
105
+ it "should pass along options" do
106
+ result = mock('result')
107
+ @session.should_receive(:delete).once.with(@path, { :sandbox => true }).and_return(result)
108
+
109
+ @entry.delete(:sandbox => true)
110
+ end
111
+ end
112
+
113
+ describe "#download" do
114
+ it "should delegate to the session and return the result" do
115
+ result = mock('result')
116
+ @session.should_receive(:download).once.with(@path, {}).and_return(result)
117
+
118
+ @entry.download.should eql(result)
119
+ end
120
+
121
+ it "should pass along options" do
122
+ result = mock('result')
123
+ @session.should_receive(:download).once.with(@path, { :sandbox => true }).and_return(result)
124
+
125
+ @entry.download(:sandbox => true)
126
+ end
127
+ end
128
+
129
+ describe "#link" do
130
+ it "should delegate to the session and return the result" do
131
+ result = mock('result')
132
+ @session.should_receive(:link).once.with(@path, {}).and_return(result)
133
+
134
+ @entry.link.should eql(result)
135
+ end
136
+
137
+ it "should pass along options" do
138
+ result = mock('result')
139
+ @session.should_receive(:link).once.with(@path, { :sandbox => true }).and_return(result)
140
+
141
+ @entry.link(:sandbox => true)
142
+ end
143
+ end
144
+ end
@@ -0,0 +1,122 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ def make_file_hash
4
+ {
5
+ :size => rand(1024*1024),
6
+ :path => "/path/to/#{rand(100)}",
7
+ :is_dir => (rand(2) == 0 ? true : false),
8
+ :mtime => (Time.now - rand(60*60*24*30)).to_i,
9
+ :latest => (rand(2) == 0 ? true : false)
10
+ }
11
+ end
12
+
13
+ describe Dropbox::Event do
14
+ before :each do
15
+ @metadata = {
16
+ '1' => {
17
+ '10' => [ 100, 101, 102 ],
18
+ '11' => [ 110, 111 ]
19
+ },
20
+ '2' => {
21
+ '20' => [ 200, 201 ],
22
+ '21' => [ 210 ]
23
+ }
24
+ }
25
+ @event = Dropbox::Event.new(@metadata.to_json)
26
+ end
27
+
28
+ describe "#user_ids" do
29
+ it "should return all the user ID's as integers" do
30
+ @event.user_ids.sort.should eql([ 1, 2 ])
31
+ end
32
+ end
33
+
34
+ describe "#entries" do
35
+ describe "with no arguments" do
36
+ it "should return all the entries as Dropbox::Revision instances" do
37
+ entries = @event.entries
38
+ entries.size.should eql(8)
39
+ @metadata.each do |uid, ns|
40
+ ns.each do |nid, js|
41
+ js.each do |jid|
42
+ entries.any? { |entry| entry.user_id == uid.to_i and entry.namespace_id == nid.to_i and entry.journal_id == jid.to_i }.should be_true
43
+ end
44
+ end
45
+ end
46
+ end
47
+
48
+ it "should return a new array" do
49
+ entries = @event.entries
50
+ entries.clear
51
+ @event.entries.should_not be_empty
52
+ end
53
+ end
54
+
55
+ describe "with a user ID" do
56
+ it "should return all the entries belonging to that user as Dropbox::Revision instances" do
57
+ entries = @event.entries(2)
58
+ entries.size.should eql(3)
59
+ @metadata['2'].each do |nid, js|
60
+ js.each do |jid|
61
+ entries.any? { |entry| entry.user_id == 2 and entry.namespace_id == nid.to_i and entry.journal_id == jid.to_i }.should be_true
62
+ end
63
+ end
64
+ end
65
+
66
+ it "should return a new array" do
67
+ entries = @event.entries(2)
68
+ entries.clear
69
+ @event.entries(2).should_not be_empty
70
+ end
71
+
72
+ it "should return an empty array for unknown user ID's" do
73
+ @event.entries('foo').should be_empty
74
+ end
75
+ end
76
+ end
77
+
78
+ describe "#load_metadata" do
79
+ before :each do
80
+ @session = mock('Dropbox::Session')
81
+ end
82
+
83
+ it "should call Dropbox::Session#event_metadata" do
84
+ @session.should_receive(:event_metadata).once.with(@metadata.to_json, {}).and_return({})
85
+ @event.load_metadata(@session)
86
+ end
87
+
88
+ it "should pass options to Dropbox::Session#event_metadata" do
89
+ @session.should_receive(:event_metadata).once.with(@metadata.to_json, :root => 'dropbox').and_return({})
90
+ @event.load_metadata(@session, :root => 'dropbox')
91
+ end
92
+
93
+ it "should call Dropbox::Revision#process_metadata on all the revisions, passing symbolized keys" do
94
+ metadata = {
95
+ '1' => {
96
+ '10' => {
97
+ '100' => make_file_hash,
98
+ '101' => make_file_hash,
99
+ '102' => make_file_hash,
100
+ },
101
+ '11' => {
102
+ '110' => make_file_hash,
103
+ '111' => make_file_hash,
104
+ }
105
+ },
106
+ '2' => {
107
+ '20' => {
108
+ '200' => { :error => 403 },
109
+ '201' => { :error => 403 }
110
+ },
111
+ '21' => {
112
+ '210' => { :error => 403 }
113
+ }
114
+ }
115
+ }
116
+ @session.stub!(:event_metadata).and_return(metadata)
117
+
118
+ @event.entries.each { |entry| entry.should_receive(:process_metadata).once.with(metadata[entry.user_id.to_s][entry.namespace_id.to_s][entry.journal_id.to_s]) }
119
+ @event.load_metadata(@session)
120
+ end
121
+ end
122
+ end
@@ -0,0 +1,367 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ def pretend_content_and_metadata_is_loaded(revision, session, options={})
4
+ content = options[:content] || "Example Content"
5
+ metadata = options[:metadata] || {
6
+ :size => (options[:size] || rand(1024*1024)),
7
+ :path => (options[:path] || "/path/to/#{rand 100}"),
8
+ :is_dir => options[:is_dir].to_bool,
9
+ :mtime => (options[:mtime] || (Time.now.to_i - rand(60*60*24*30))),
10
+ :latest => options[:latest].to_bool
11
+ }
12
+
13
+ session.stub!(:event_content).and_return([ content, metadata ])
14
+ revision.load session
15
+ return metadata
16
+ end
17
+
18
+ def pretend_error_occurred(revision, error=404)
19
+ revision.process_metadata :error => error
20
+ return error
21
+ end
22
+
23
+ describe Dropbox::Revision do
24
+ before :each do
25
+ @uid = rand(1000)
26
+ @nid = rand(1000)
27
+ @jid = rand(1000)
28
+ @revision = Dropbox::Revision.new(@uid, @nid, @jid)
29
+ end
30
+
31
+ describe ".new" do
32
+ it "should set the user, namespace, and journal ID" do
33
+ @revision.user_id.should eql(@uid)
34
+ @revision.namespace_id.should eql(@nid)
35
+ @revision.journal_id.should eql(@jid)
36
+ end
37
+
38
+ it "should not have an error" do
39
+ @revision.should_not be_error
40
+ @revision.error.should be_nil
41
+ end
42
+
43
+ it "should not have content loaded" do
44
+ @revision.should_not be_content_loaded
45
+ end
46
+
47
+ it "should not have metadata loaded" do
48
+ @revision.should_not be_metadata_loaded
49
+ end
50
+ end
51
+
52
+ describe "#identifier" do
53
+ it "should be the Dropbox event identifier for the revision" do
54
+ @revision.identifier.should eql([ @uid, @nid, @jid ].map(&:to_s).join(':'))
55
+ end
56
+ end
57
+
58
+ describe "#load" do
59
+ before :each do
60
+ @session = mock('Dropbox::Session')
61
+ end
62
+
63
+ it "should call Dropbox::API.event_content" do
64
+ @session.should_receive(:event_content).once.with(@revision.identifier, {}).and_return([ "A", {} ])
65
+ @revision.load @session
66
+ end
67
+
68
+ it "should pass options to the session" do
69
+ @session.should_receive(:event_content).once.with(@revision.identifier, { :root => 'dropbox' }).and_return([ "A", {} ])
70
+ @revision.load @session, :root => 'dropbox'
71
+ end
72
+
73
+ it "should set the content and metadata" do
74
+ @session.stub!(:event_content).and_return([ "content", { :number => 123 } ])
75
+ @revision.load @session
76
+
77
+ @revision.content.should eql("content")
78
+ @revision.number.should eql(123)
79
+ end
80
+
81
+ it "should work with metadata string keys" do
82
+ @session.stub!(:event_content).and_return([ "content", { :number => 123 } ])
83
+ @revision.load @session
84
+
85
+ @revision.content.should eql("content")
86
+ @revision.number.should eql(123)
87
+ end
88
+
89
+ it "should set the size attribute to nil if it's -1" do
90
+ @session.stub!(:event_content).and_return([ "content", { :size => -1 } ])
91
+ @revision.load @session
92
+
93
+ @revision.size.should be_nil
94
+ end
95
+
96
+ it "should set the mtime attribute to nil if it's -1" do
97
+ @session.stub!(:event_content).and_return([ "content", { :mtime => -1 } ])
98
+ @revision.load @session
99
+
100
+ @revision.mtime.should be_nil
101
+ end
102
+
103
+ it "should convert the mtime attribute to a Time" do
104
+ time = Time.now.to_i
105
+ @session.stub!(:event_content).and_return([ "content", { :mtime => time } ])
106
+ @revision.load @session
107
+
108
+ @revision.mtime.should be_kind_of(Time)
109
+ @revision.mtime.to_i.should eql(time)
110
+ end
111
+
112
+ it "should leave the mtime attribute nil if nil" do
113
+ @session.stub!(:event_content).and_return([ "content", { :mtime => nil } ])
114
+ @revision.load @session
115
+
116
+ @revision.mtime.should be_nil
117
+ end
118
+
119
+ it "should convert the ts attribute to a Time" do
120
+ @session.stub!(:event_content).and_return([ "content", { :ts => "Thu, 21 Jan 2010 00:09:39 +0000" } ])
121
+ @revision.load @session
122
+
123
+ @revision.ts.should be_kind_of(Time)
124
+ @revision.ts.to_i.should eql(1264032579)
125
+ end
126
+
127
+ it "should leave the ts attribute nil if nil" do
128
+ @session.stub!(:event_content).and_return([ "content", { :ts => nil } ])
129
+ @revision.load @session
130
+
131
+ @revision.ts.should be_nil
132
+ end
133
+ end
134
+
135
+ describe "#content_loaded?" do
136
+ it "should return true if the content is loaded" do
137
+ pretend_content_and_metadata_is_loaded @revision, @session
138
+ @revision.should be_content_loaded
139
+ end
140
+ end
141
+
142
+ describe "#metadata_loaded?" do
143
+ it "should return true if the metadata is loaded" do
144
+ pretend_content_and_metadata_is_loaded @revision, @session
145
+ @revision.should be_metadata_loaded
146
+ end
147
+ end
148
+
149
+ describe "#latest?" do
150
+ it "should raise an exception if the metadata is not yet loaded" do
151
+ lambda { @revision.latest? }.should raise_error(Dropbox::NotLoadedError)
152
+ end
153
+
154
+ it "should return the true if latest is true" do
155
+ pretend_content_and_metadata_is_loaded @revision, @session, :latest => true
156
+ @revision.should be_latest
157
+ end
158
+
159
+ it "should return the false if latest is false" do
160
+ pretend_content_and_metadata_is_loaded @revision, @session, :latest => false
161
+ @revision.should_not be_latest
162
+ end
163
+ end
164
+
165
+ describe "#directory?" do
166
+ it "should raise an exception if the metadata is not yet loaded" do
167
+ lambda { @revision.directory? }.should raise_error(Dropbox::NotLoadedError)
168
+ end
169
+
170
+ it "should return true if is_dir is true" do
171
+ pretend_content_and_metadata_is_loaded @revision, @session, :is_dir => true
172
+ @revision.should be_directory
173
+ end
174
+
175
+ it "should return false if is_dir is false" do
176
+ pretend_content_and_metadata_is_loaded @revision, @session, :is_dir => false
177
+ @revision.should_not be_directory
178
+ end
179
+ end
180
+
181
+ describe "#modified" do
182
+ it "should raise an exception if the metadata is not yet loaded" do
183
+ lambda { @revision.modified }.should raise_error(Dropbox::NotLoadedError)
184
+ end
185
+
186
+ it "should return the mtime attribute" do
187
+ md = pretend_content_and_metadata_is_loaded(@revision, @session)
188
+ @revision.modified.should eql(md[:mtime])
189
+ end
190
+ end
191
+
192
+ describe "#error?" do
193
+ it "should return true if there was an error" do
194
+ pretend_error_occurred @revision
195
+ @revision.should be_error
196
+ end
197
+
198
+ it "should return false if there was not an error" do
199
+ pretend_content_and_metadata_is_loaded @revision, @session
200
+ @revision.should_not be_error
201
+ end
202
+ end
203
+
204
+ describe "#deleted?" do
205
+ it "should raise an exception if the metadata is not yet loaded" do
206
+ lambda { @revision.deleted? }.should raise_error(Dropbox::NotLoadedError)
207
+ end
208
+
209
+ it "should return true if mtime and size are nil" do
210
+ pretend_content_and_metadata_is_loaded(@revision, @session)
211
+ @revision.stub!(:mtime).and_return(nil)
212
+ @revision.stub!(:size).and_return(nil)
213
+ @revision.should be_deleted
214
+ end
215
+
216
+ it "should return false if mtime and size are not nil" do
217
+ pretend_content_and_metadata_is_loaded(@revision, @session)
218
+ @revision.stub!(:mtime).and_return(Time.now)
219
+ @revision.stub!(:size).and_return(123)
220
+ @revision.should_not be_deleted
221
+ end
222
+ end
223
+
224
+ describe "#content" do
225
+ it "should raise an exception if the content is not yet loaded" do
226
+ lambda { @revision.content }.should raise_error(Dropbox::NotLoadedError)
227
+ end
228
+
229
+ it "should return the file content" do
230
+ pretend_content_and_metadata_is_loaded @revision, @session
231
+ @revision.content.should eql("Example Content")
232
+ end
233
+ end
234
+
235
+ describe "#method_missing" do
236
+ before :each do
237
+ pretend_content_and_metadata_is_loaded @revision, @session, :size => 123
238
+ end
239
+
240
+ it "should return a metadata attribute by name" do
241
+ @revision.size.should eql(123)
242
+ end
243
+
244
+ it "... unless arguments are provided" do
245
+ lambda { @revision.size(123) }.should raise_error(NoMethodError)
246
+ end
247
+
248
+ it "should raise NoMethodError for an unknown attribute" do
249
+ lambda { @revision.foobar }.should raise_error(NoMethodError)
250
+ end
251
+ end
252
+
253
+ describe "#metadata_for_latest_revision" do
254
+ it "should raise an error if metadata has not yet been loaded" do
255
+ lambda { @revision.metadata_for_latest_revision @session }.should raise_error(Dropbox::NotLoadedError)
256
+ end
257
+
258
+ it "should call Dropbox::API.metadata with its path" do
259
+ pretend_content_and_metadata_is_loaded @revision, @session
260
+ @session.should_receive(:metadata).once.with(@revision.path, {})
261
+ @revision.metadata_for_latest_revision @session
262
+ end
263
+
264
+ it "should pass along options" do
265
+ pretend_content_and_metadata_is_loaded @revision, @session
266
+ @session.should_receive(:metadata).once.with(@revision.path, { :root => 'dropbox' })
267
+ @revision.metadata_for_latest_revision @session, :root => 'dropbox'
268
+ end
269
+ end
270
+
271
+ describe "#process_metadata" do
272
+ describe "with an error" do
273
+ before :each do
274
+ @metadata = { :error => 403 }
275
+ end
276
+
277
+ it "should set the error attribute" do
278
+ @revision.process_metadata @metadata
279
+ @revision.error.should eql(403)
280
+ end
281
+
282
+ it "... unless the metadata has already been loaded" do
283
+ pretend_content_and_metadata_is_loaded @revision, @session
284
+ @revision.process_metadata @metadata
285
+ @revision.error.should be_nil
286
+ end
287
+
288
+ it "should not change the metadata" do
289
+ md = pretend_content_and_metadata_is_loaded @revision, @session
290
+ @revision.process_metadata @metadata
291
+ md.each { |key, val| @revision.send(key).should eql(val) }
292
+ end
293
+ end
294
+
295
+ describe "with metadata" do
296
+ before :each do
297
+ @metadata = {
298
+ :size => rand(1024*1024),
299
+ :path => "/path/to/#{rand 100}",
300
+ :is_dir => (rand(2) == 0),
301
+ :mtime => (Time.now.to_i - rand(60*60*24*30)),
302
+ :latest => (rand(2) == 0)
303
+ }
304
+ end
305
+
306
+ it "should clear the error attribute" do
307
+ pretend_error_occurred @revision
308
+ @revision.process_metadata @metadata
309
+ @revision.error.should be_nil
310
+ end
311
+
312
+ it "should assign metadata" do
313
+ @revision.process_metadata @metadata
314
+ @metadata.each { |key, val| @revision.send(key).should eql(val) unless key == :mtime }
315
+ end
316
+
317
+ it "should clear and overwrite old metadata" do
318
+ pretend_content_and_metadata_is_loaded @revision, @session
319
+ @revision.process_metadata @metadata
320
+ @metadata.each { |key, val| @revision.send(key).should eql(val) unless key == :mtime }
321
+ end
322
+
323
+ it "should set the size attribute to nil if it's -1" do
324
+ @metadata[:size] = -1
325
+ @revision.process_metadata @metadata
326
+ @revision.size.should be_nil
327
+ end
328
+
329
+ it "should set the mtime attribute to nil if it's -1" do
330
+ @metadata[:mtime] = -1
331
+ @revision.process_metadata @metadata
332
+ @revision.mtime.should be_nil
333
+ end
334
+
335
+ it "should convert the mtime attribute to a Time" do
336
+ time = Time.now.to_i
337
+ @metadata[:mtime] = time
338
+ @revision.process_metadata @metadata
339
+
340
+ @revision.mtime.should be_kind_of(Time)
341
+ @revision.mtime.to_i.should eql(time)
342
+ end
343
+
344
+ it "should leave the mtime attribute nil if nil" do
345
+ @metadata[:mtime] = nil
346
+ @revision.process_metadata @metadata
347
+
348
+ @revision.mtime.should be_nil
349
+ end
350
+
351
+ it "should convert the ts attribute to a Time" do
352
+ @metadata[:ts] = "Thu, 21 Jan 2010 00:09:39 +0000"
353
+ @revision.process_metadata @metadata
354
+
355
+ @revision.ts.should be_kind_of(Time)
356
+ @revision.ts.to_i.should eql(1264032579)
357
+ end
358
+
359
+ it "should leave the ts attribute nil if nil" do
360
+ @metadata[:ts] = nil
361
+ @revision.process_metadata @metadata
362
+
363
+ @revision.ts.should be_nil
364
+ end
365
+ end
366
+ end
367
+ end