rdropbox 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,778 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ def url_args(url)
4
+ return {} unless url.include?('?')
5
+ _, back = url.split('?')
6
+ return {} unless back
7
+ back.split('&').map { |comp| comp.split('=') }.to_hash
8
+ end
9
+
10
+ def should_receive_api_method_with_arguments(object, method, api_method, arguments, response, path=nil, root=nil)
11
+ object.should_receive(method).once do |url|
12
+ front = url.split('?').first
13
+ front.should eql("#{Dropbox::ALTERNATE_HOSTS[api_method] || Dropbox::HOST}/#{Dropbox::VERSION}/#{api_method}#{'/' + root if root}#{'/' + path if path}")
14
+
15
+ query_params = url_args(url)
16
+ query_params.each { |key, val| val.should eql(arguments[key.to_sym]) }
17
+ arguments.each { |key, _| query_params.should include(key.to_s) }
18
+ response
19
+ end
20
+ end
21
+
22
+ def stub_for_upload_testing
23
+ @consumer_mock.stub!(:key).and_return("consumer key")
24
+ @consumer_mock.stub!(:secret).and_return("consumer secret")
25
+ @consumer_mock.stub!(:sign!).and_return { |req, _| req.stub!(:to_hash).and_return('authorization' => ["Oauth", "test"]) }
26
+
27
+ @token_mock.stub!(:token).and_return("access token")
28
+ @token_mock.stub!(:secret).and_return("access secret")
29
+
30
+ @response.stub!(:kind_of?).with(Net::HTTPSuccess).and_return(true)
31
+ @response.stub!(:body).and_return('{"test":"val"}')
32
+
33
+ Net::HTTP.stub!(:start).and_return(@response)
34
+ end
35
+
36
+ def response_acts_as(subclass)
37
+ @response.stub(:kind_of?).and_return(false)
38
+ @response.stub(:kind_of?).with(subclass).and_return(true) if subclass
39
+ end
40
+
41
+ describe Dropbox::API do
42
+ before :each do
43
+ @consumer_mock = mock("OAuth::Consumer")
44
+ token_mock = mock("OAuth::RequestToken")
45
+ @token_mock = mock("OAuth::AccessToken")
46
+ token_mock.stub!(:get_access_token).and_return(@token_mock)
47
+ @consumer_mock.stub!(:get_request_token).and_return(token_mock)
48
+ OAuth::Consumer.stub!(:new).and_return(@consumer_mock)
49
+
50
+ @session = Dropbox::Session.new('foo', 'bar')
51
+ @session.authorize
52
+
53
+ @response = mock('Net::HTTPResponse')
54
+ @response.stub!(:kind_of?).with(Net::HTTPSuccess).and_return(true)
55
+ @response.stub!(:code).and_return(200)
56
+ @response.stub!(:body).and_return("response body")
57
+ end
58
+
59
+ describe "#account" do
60
+ it "should call the /account/info API method" do
61
+ @response.stub!(:body).and_return('{"a":"b"}')
62
+ should_receive_api_method_with_arguments @token_mock, :get, 'account/info', {}, @response
63
+ @session.account
64
+ end
65
+
66
+ it "should convert the result into a struct" do
67
+ @response.stub!(:body).and_return( { :foo => :bar, :baz => { :hey => :you } }.to_json)
68
+ @token_mock.stub!(:get).and_return(@response)
69
+ result = @session.account
70
+ result.foo.should eql('bar')
71
+ result.baz.hey.should eql('you')
72
+ end
73
+ end
74
+
75
+ describe "#download" do
76
+ it "should call the files API method" do
77
+ should_receive_api_method_with_arguments @token_mock, :get, 'files', {}, @response, 'path/to/file', 'sandbox'
78
+ @session.download "path/to/file"
79
+ end
80
+
81
+ it "should strip a leading slash" do
82
+ should_receive_api_method_with_arguments @token_mock, :get, 'files', {}, @response, 'path/to/file', 'sandbox'
83
+ @session.download "/path/to/file"
84
+ end
85
+
86
+ it "should return the body of the response" do
87
+ @token_mock.stub!(:get).and_return(@response)
88
+ @session.download("path/to/file").should eql("response body")
89
+ end
90
+
91
+ it "should check the path" do
92
+ path = "test/path"
93
+ Dropbox.should_receive(:check_path).once.with(path).and_return(path)
94
+ @token_mock.stub!(:get).and_return(@response)
95
+
96
+ @session.download(path)
97
+ end
98
+ end
99
+
100
+ describe "#copy" do
101
+ before :each do
102
+ @response.stub!(:body).and_return('{"a":"b"}')
103
+ end
104
+
105
+ it "should call the fileops/copy API method" do
106
+ should_receive_api_method_with_arguments @token_mock, :post, 'fileops/copy', { :from_path => 'source%2Ffile', :to_path => 'dest%2Ffile', :root => 'sandbox' }, @response
107
+ @session.copy 'source/file', 'dest/file'
108
+ end
109
+
110
+ it "should return the metadata as a struct" do
111
+ @response.stub!(:body).and_return( { :foo => :bar, :baz => { :hey => :you } }.to_json)
112
+ @token_mock.stub!(:post).and_return(@response)
113
+
114
+ result = @session.copy('a', 'b')
115
+ result.foo.should eql('bar')
116
+ result.baz.hey.should eql('you')
117
+ end
118
+
119
+ it "should strip a leading slash from source" do
120
+ should_receive_api_method_with_arguments @token_mock, :post, 'fileops/copy', { :from_path => 'source%2Ffile', :to_path => 'dest%2Ffile', :root => 'sandbox' }, @response
121
+ @session.copy '/source/file', 'dest/file'
122
+ end
123
+
124
+ it "should strip a leading slash from target" do
125
+ should_receive_api_method_with_arguments @token_mock, :post, 'fileops/copy', { :from_path => 'source%2Ffile', :to_path => 'dest%2Ffile', :root => 'sandbox' }, @response
126
+ @session.copy 'source/file', '/dest/file'
127
+ end
128
+
129
+ it "should set the target file name to the source file name if the target is a directory path" do
130
+ should_receive_api_method_with_arguments @token_mock, :post, 'fileops/copy', { :from_path => 'source%2Ffile', :to_path => 'dest%2Ffile', :root => 'sandbox' }, @response
131
+ @session.copy 'source/file', 'dest/'
132
+ end
133
+
134
+ it "should re-raise 404's as FileNotFoundErrors" do
135
+ response_acts_as Net::HTTPNotFound
136
+ @token_mock.stub!(:post).and_return(@response)
137
+
138
+ lambda { @session.copy('a', 'b') }.should raise_error(Dropbox::FileNotFoundError)
139
+ end
140
+
141
+ it "should re-raise 403's as FileExistsErrors" do
142
+ response_acts_as Net::HTTPForbidden
143
+ @token_mock.stub!(:post).and_return(@response)
144
+
145
+ lambda { @session.copy('a', 'b') }.should raise_error(Dropbox::FileExistsError)
146
+ end
147
+
148
+ it "should raise other errors unmodified" do
149
+ @response.stub(:kind_of?).and_return(false)
150
+ @token_mock.stub!(:post).and_return(@response)
151
+
152
+ lambda { @session.copy('a', 'b') }.should raise_error(Dropbox::UnsuccessfulResponseError)
153
+ end
154
+
155
+ it "should check the source and destination paths" do
156
+ source_path = "source/path"
157
+ dest_path = "dest/path"
158
+ Dropbox.should_receive(:check_path).once.with(source_path).and_return(source_path)
159
+ Dropbox.should_receive(:check_path).once.with(dest_path).and_return(dest_path)
160
+ @token_mock.stub!(:post).and_return(@response)
161
+
162
+ @session.copy(source_path, dest_path)
163
+ end
164
+ end
165
+
166
+ describe "#move" do
167
+ before :each do
168
+ @response.stub!(:body).and_return('{"a":"b"}')
169
+ end
170
+
171
+ it "should call the fileops/move API method" do
172
+ should_receive_api_method_with_arguments @token_mock, :post, 'fileops/move', { :from_path => 'source%2Ffile', :to_path => 'dest%2Ffile', :root => 'sandbox' }, @response
173
+ @session.move 'source/file', 'dest/file'
174
+ end
175
+
176
+ it "should return the metadata as a struct" do
177
+ @response.stub!(:body).and_return( { :foo => :bar, :baz => { :hey => :you } }.to_json)
178
+ @token_mock.stub!(:post).and_return(@response)
179
+
180
+ result = @session.move('a', 'b')
181
+ result.foo.should eql('bar')
182
+ result.baz.hey.should eql('you')
183
+ end
184
+
185
+ it "should strip a leading slash from source" do
186
+ should_receive_api_method_with_arguments @token_mock, :post, 'fileops/move', { :from_path => 'source%2Ffile', :to_path => 'dest%2Ffile', :root => 'sandbox' }, @response
187
+ @session.move '/source/file', 'dest/file'
188
+ end
189
+
190
+ it "should strip a leading slash from target" do
191
+ should_receive_api_method_with_arguments @token_mock, :post, 'fileops/move', { :from_path => 'source%2Ffile', :to_path => 'dest%2Ffile', :root => 'sandbox' }, @response
192
+ @session.move 'source/file', '/dest/file'
193
+ end
194
+
195
+ it "should set the target file name to the source file name if the target is a directory path" do
196
+ should_receive_api_method_with_arguments @token_mock, :post, 'fileops/move', { :from_path => 'source%2Ffile', :to_path => 'dest%2Ffile', :root => 'sandbox' }, @response
197
+ @session.move 'source/file', 'dest/'
198
+ end
199
+
200
+ it "should re-raise 404's as FileNotFoundErrors" do
201
+ response_acts_as Net::HTTPNotFound
202
+ @token_mock.stub!(:post).and_return(@response)
203
+
204
+ lambda { @session.move('a', 'b') }.should raise_error(Dropbox::FileNotFoundError)
205
+ end
206
+
207
+ it "should re-raise 403's as FileExistsErrors" do
208
+ response_acts_as Net::HTTPForbidden
209
+ @token_mock.stub!(:post).and_return(@response)
210
+
211
+ lambda { @session.move('a', 'b') }.should raise_error(Dropbox::FileExistsError)
212
+ end
213
+
214
+ it "should raise other errors unmodified" do
215
+ response_acts_as nil
216
+ @token_mock.stub!(:post).and_return(@response)
217
+
218
+ lambda { @session.move('a', 'b') }.should raise_error(Dropbox::UnsuccessfulResponseError)
219
+ end
220
+
221
+ it "should check the source and destination paths" do
222
+ source_path = "source/path"
223
+ dest_path = "dest/path"
224
+ Dropbox.should_receive(:check_path).once.with(source_path).and_return(source_path)
225
+ Dropbox.should_receive(:check_path).once.with(dest_path).and_return(dest_path)
226
+ @token_mock.stub!(:post).and_return(@response)
227
+
228
+ @session.move(source_path, dest_path)
229
+ end
230
+ end
231
+
232
+ describe "#rename" do
233
+ it "should raise an error if the new name has a slash in it" do
234
+ lambda { @session.rename 'file', 'new/name' }.should raise_error(ArgumentError)
235
+ end
236
+
237
+ it "should call move with the appropriate path and return the result of the call" do
238
+ @session.should_receive(:move).once.with('old/path/to/file', 'old/path/to/new_file', :mode => :sandbox).and_return(@response)
239
+ @session.rename('old/path/to/file', 'new_file', :mode => :sandbox).should eql(@response)
240
+ end
241
+ end
242
+
243
+ describe "#create_folder" do
244
+ before :each do
245
+ @response.stub!(:body).and_return('{"a":"b"}')
246
+ end
247
+
248
+ it "should call the fileops/create_folder API method" do
249
+ should_receive_api_method_with_arguments @token_mock, :post, 'fileops/create_folder', { :path => 'new%2Ffolder', :root => 'sandbox' }, @response
250
+ @session.create_folder 'new/folder'
251
+ end
252
+
253
+ it "should return the metadata as a struct" do
254
+ @response.stub!(:body).and_return( { :foo => :bar, :baz => { :hey => :you } }.to_json)
255
+ @token_mock.stub!(:post).and_return(@response)
256
+
257
+ result = @session.create_folder('a')
258
+ result.foo.should eql('bar')
259
+ result.baz.hey.should eql('you')
260
+ end
261
+
262
+ it "should strip a leading slash from the path" do
263
+ should_receive_api_method_with_arguments @token_mock, :post, 'fileops/create_folder', { :path => 'new%2Ffolder', :root => 'sandbox' }, @response
264
+ @session.create_folder '/new/folder'
265
+ end
266
+
267
+ it "should strip a trailing slash from the path" do
268
+ should_receive_api_method_with_arguments @token_mock, :post, 'fileops/create_folder', { :path => 'new%2Ffolder', :root => 'sandbox' }, @response
269
+ @session.create_folder 'new/folder/'
270
+ end
271
+
272
+ it "should re-raise 403's as FileExistsErrors" do
273
+ response_acts_as Net::HTTPForbidden
274
+ @token_mock.stub!(:post).and_return(@response)
275
+
276
+ lambda { @session.create_folder('a') }.should raise_error(Dropbox::FileExistsError)
277
+ end
278
+
279
+ it "should raise other errors unmodified" do
280
+ response_acts_as nil
281
+ @token_mock.stub!(:post).and_return(@response)
282
+
283
+ lambda { @session.create_folder('a') }.should raise_error(Dropbox::UnsuccessfulResponseError)
284
+ end
285
+
286
+ it "should check the path" do
287
+ path = "source/path"
288
+ Dropbox.should_receive(:check_path).once.with(path).and_return(path)
289
+ @token_mock.stub!(:post).and_return(@response)
290
+
291
+ @session.create_folder(path)
292
+ end
293
+ end
294
+
295
+ describe "#delete" do
296
+ it "should call the API method fileops/delete" do
297
+ should_receive_api_method_with_arguments @token_mock, :post, 'fileops/delete', { :path => 'some%2Ffile', :root => 'sandbox' }, @response
298
+ @session.delete 'some/file'
299
+ end
300
+
301
+ it "should return true" do
302
+ @token_mock.stub!(:post).and_return(@response)
303
+ @session.delete('some/file').should be_true
304
+ end
305
+
306
+ it "should strip a leading slash from the path" do
307
+ should_receive_api_method_with_arguments @token_mock, :post, 'fileops/delete', { :path => 'some%2Ffile', :root => 'sandbox' }, @response
308
+ @session.delete '/some/file'
309
+ end
310
+
311
+ it "should strip a trailing slash from the path" do
312
+ should_receive_api_method_with_arguments @token_mock, :post, 'fileops/delete', { :path => 'some%2Ffile', :root => 'sandbox' }, @response
313
+ @session.delete 'some/file/'
314
+ end
315
+
316
+ it "should re-raise 404's as FileNotFoundErrors" do
317
+ response_acts_as Net::HTTPNotFound
318
+ @token_mock.stub!(:post).and_return(@response)
319
+
320
+ lambda { @session.delete('a') }.should raise_error(Dropbox::FileNotFoundError)
321
+ end
322
+
323
+ it "should raise other errors unmodified" do
324
+ response_acts_as nil
325
+ @token_mock.stub!(:post).and_return(@response)
326
+
327
+ lambda { @session.delete('a') }.should raise_error(Dropbox::UnsuccessfulResponseError)
328
+ end
329
+
330
+ it "should check the path" do
331
+ path = "source/path"
332
+ Dropbox.should_receive(:check_path).once.with(path).and_return(path)
333
+ @token_mock.stub!(:post).and_return(@response)
334
+
335
+ @session.delete(path)
336
+ end
337
+ end
338
+
339
+ describe "#link" do
340
+ before :each do
341
+ @response.stub!(:code).and_return(304)
342
+ response_acts_as Net::HTTPFound
343
+ @response.stub!(:[]).and_return("new location")
344
+ end
345
+
346
+ it "should call the API method links" do
347
+ should_receive_api_method_with_arguments @token_mock, :get, 'links', {}, @response, 'some/file', 'sandbox'
348
+ @session.link 'some/file'
349
+ end
350
+
351
+ it "should strip a leading slash" do
352
+ should_receive_api_method_with_arguments @token_mock, :get, 'links', {}, @response, 'some/file', 'sandbox'
353
+ @session.link '/some/file'
354
+ end
355
+
356
+ it "should rescue 304's and return the Location header" do
357
+ should_receive_api_method_with_arguments @token_mock, :get, 'links', {}, @response, 'some/file', 'sandbox'
358
+ lambda { @session.link('some/file').should eql("new location") }.should_not raise_error
359
+ end
360
+
361
+ it "should re-raise other errors unmodified" do
362
+ response_acts_as nil
363
+ @token_mock.stub!(:get).and_return(@response)
364
+ lambda { @session.link('a') }.should raise_error(Dropbox::UnsuccessfulResponseError)
365
+ end
366
+
367
+ it "should check the path" do
368
+ path = "source/path"
369
+ Dropbox.should_receive(:check_path).once.with(path).and_return(path)
370
+ @token_mock.stub!(:get).and_return(@response)
371
+
372
+ @session.link(path)
373
+ end
374
+ end
375
+
376
+ describe "#metadata" do
377
+ before :each do
378
+ @response.stub!(:body).and_return('{"a":"b"}')
379
+ end
380
+
381
+ it "should call the API method metadata" do
382
+ should_receive_api_method_with_arguments @token_mock, :get, 'metadata', { :list => 'true' }, @response, 'some/file', 'sandbox'
383
+ @session.metadata 'some/file'
384
+ end
385
+
386
+ it "should strip a leading slash" do
387
+ should_receive_api_method_with_arguments @token_mock, :get, 'metadata', { :list => 'true' }, @response, 'some/file', 'sandbox'
388
+ @session.metadata '/some/file'
389
+ end
390
+
391
+ it "should set file_limit if :limit is set" do
392
+ should_receive_api_method_with_arguments @token_mock, :get, 'metadata', { :list => 'true', :file_limit => '123' }, @response, 'some/file', 'sandbox'
393
+ @session.metadata 'some/file', :limit => 123
394
+ end
395
+
396
+ it "should set list=false if :suppress_list is set" do
397
+ should_receive_api_method_with_arguments @token_mock, :get, 'metadata', { :list => 'false' }, @response, 'some/file', 'sandbox'
398
+ @session.metadata 'some/file', :suppress_list => true
399
+ end
400
+
401
+ it "should rescue 406's and re-raise them as TooManyEntriesErrors" do
402
+ response_acts_as Net::HTTPNotAcceptable
403
+ @token_mock.stub!(:get).and_return(@response)
404
+
405
+ lambda { @session.metadata('a') }.should raise_error(Dropbox::TooManyEntriesError)
406
+ end
407
+
408
+ it "should rescue 404's and re-raise them as FileNotFoundErrors" do
409
+ response_acts_as Net::HTTPNotFound
410
+ @token_mock.stub!(:get).and_return(@response)
411
+
412
+ lambda { @session.metadata('a') }.should raise_error(Dropbox::FileNotFoundError)
413
+ end
414
+
415
+ it "should re-raise other errors unmodified" do
416
+ response_acts_as nil
417
+ @token_mock.stub!(:get).and_return(@response)
418
+
419
+ lambda { @session.metadata('a') }.should raise_error(Dropbox::UnsuccessfulResponseError)
420
+ end
421
+
422
+ it "should check the path" do
423
+ path = "source/path"
424
+ Dropbox.should_receive(:check_path).once.with(path).and_return(path)
425
+ @token_mock.stub!(:get).and_return(@response)
426
+
427
+ @session.metadata(path)
428
+ end
429
+
430
+ it "should recursively convert the modification date into a Time" do
431
+ time = Time.now
432
+ @response.stub!(:body).and_return({ :modified => time.to_s, :hsh => { :modified => time.to_s } }.to_json)
433
+ @token_mock.stub!(:get).and_return(@response)
434
+
435
+ response = @session.metadata('path')
436
+
437
+ response.modified.should be_kind_of(Time)
438
+ response.modified.to_i.should == time.to_i
439
+ response.hsh.modified.should be_kind_of(Time)
440
+ response.hsh.modified.to_i.should == time.to_i
441
+ end
442
+
443
+ it "should add a directory? item recursively" do
444
+ @response.stub!(:body).and_return({ :is_dir => true, :hsh => { :is_dir => false } }.to_json)
445
+ @token_mock.stub!(:get).and_return(@response)
446
+
447
+ response = @session.metadata('path')
448
+
449
+ response.directory?.should be_true
450
+ response.hsh.directory?.should be_false
451
+ end
452
+ end
453
+
454
+ describe "#list" do
455
+ before :each do
456
+ @response = mock('metadata')
457
+ end
458
+
459
+ it "should call the metadata method and return the contents attribute" do
460
+ @response.should_receive(:contents).once.and_return([ 'contents' ])
461
+ @session.should_receive(:metadata).once.with('my/file', an_instance_of(Hash)).and_return(@response)
462
+
463
+ @session.list('my/file').should == [ 'contents' ]
464
+ end
465
+
466
+ it "should not allow suppress_list to be set to true" do
467
+ @response.stub!(:contents)
468
+ @session.should_receive(:metadata).once.with('my/file', hash_including(:hash => true, :suppress_list => false)).and_return(@response)
469
+
470
+ @session.list('my/file', :suppress_list => true, :hash => true)
471
+ end
472
+ end
473
+
474
+ describe "#upload" do
475
+ before :each do
476
+ stub_for_upload_testing
477
+ end
478
+
479
+ it "should check the path" do
480
+ path = "dest/path"
481
+ Dropbox.should_receive(:check_path).once.with(path).and_return(path)
482
+ @session.upload(__FILE__, path)
483
+ end
484
+
485
+ describe "parameters" do
486
+ describe "given a File object" do
487
+ before :each do
488
+ @file = File.open(__FILE__)
489
+ end
490
+
491
+ after :each do
492
+ @file.close
493
+ end
494
+
495
+ it "should use the File object as the stream" do
496
+ UploadIO.should_receive(:convert!).once.with(@file, anything, File.basename(__FILE__), __FILE__)
497
+ @session.upload @file, 'remote/'
498
+ end
499
+ end
500
+
501
+ describe "given a String object" do
502
+ before :each do
503
+ @string = __FILE__
504
+ @file = File.new(__FILE__)
505
+ File.should_receive(:new).once.with(@string).and_return(@file)
506
+ end
507
+
508
+ it "should use the file at that path as the stream" do
509
+ UploadIO.should_receive(:convert!).once.with(@file, anything, File.basename(__FILE__), __FILE__)
510
+ @session.upload @string, 'remote/'
511
+ end
512
+ end
513
+
514
+ it "should raise an error if given an unknown argument type" do
515
+ lambda { @session.upload 123, 'path' }.should raise_error(ArgumentError)
516
+ end
517
+ end
518
+
519
+ describe "request" do
520
+ before :each do
521
+ @request = mock('Net::HTTPRequest')
522
+ @request.stub!(:[]=)
523
+ end
524
+
525
+ it "should strip a leading slash from the remote path" do
526
+ Net::HTTP::Post::Multipart.should_receive(:new).once do |*args|
527
+ args.first.should eql("/#{Dropbox::VERSION}/files/sandbox/path")
528
+ @request
529
+ end
530
+
531
+ @session.upload __FILE__, '/path'
532
+ end
533
+
534
+ it "should call the files API method" do
535
+ Net::HTTP::Post::Multipart.should_receive(:new).once do |*args|
536
+ args.first.should eql("/#{Dropbox::VERSION}/files/sandbox/path/to/file")
537
+ @request
538
+ end
539
+
540
+ @session.upload __FILE__, 'path/to/file'
541
+ end
542
+
543
+ it "should use the sandbox root if specified" do
544
+ Net::HTTP::Post::Multipart.should_receive(:new).once do |*args|
545
+ args.first.should eql("/#{Dropbox::VERSION}/files/sandbox/path/to/file")
546
+ @request
547
+ end
548
+
549
+ @session.upload __FILE__, 'path/to/file', :mode => :sandbox
550
+ end
551
+
552
+ it "should set the authorization content header to the signed OAuth request" do
553
+ Net::HTTP::Post::Multipart.stub!(:new).and_return(@request)
554
+ @request.should_receive(:[]=).once.with('authorization', 'Oauth, test')
555
+
556
+ @session.upload __FILE__, 'blah'
557
+ end
558
+
559
+ it "should create a multipart POST request with the 'file' parameter set to the file of type application/octet-stream" do
560
+ Net::HTTP::Post::Multipart.should_receive(:new).once.with("/#{Dropbox::VERSION}/files/sandbox/hello", hash_including('file' => an_instance_of(File))).and_return(@request)
561
+
562
+ @session.upload __FILE__, 'hello'
563
+ end
564
+
565
+ it "should send the request" do
566
+ uri = URI.parse(Dropbox::ALTERNATE_HOSTS['files'])
567
+ Net::HTTP.should_receive(:start).once.with(uri.host, uri.port).and_return(@response)
568
+
569
+ @session.upload __FILE__, 'test'
570
+ end
571
+
572
+ it "should send an SSL request" do
573
+ @session = Dropbox::Session.new('foo', 'bar', :ssl => true)
574
+ @session.authorize
575
+
576
+ uri = URI.parse(Dropbox::ALTERNATE_SSL_HOSTS['files'])
577
+ Net::HTTP.should_receive(:start).once.with(uri.host, uri.port).and_return(@response)
578
+
579
+ @session.upload __FILE__, 'test'
580
+ end
581
+ end
582
+ end
583
+
584
+ describe "#event_metadata" do
585
+ it "should call the API method event_metadata" do
586
+ @response.stub!(:body).and_return('{"a":"b"}')
587
+ should_receive_api_method_with_arguments @token_mock, :get, 'event_metadata', { :root => 'sandbox', :target_events => 'event_json' }, @response
588
+ @session.event_metadata 'event_json'
589
+ end
590
+
591
+ it "should return the JSON-parsed response" do
592
+ resp = { :some => { :json => 123 } }
593
+ @response.stub!(:body).and_return(resp.to_json)
594
+ @token_mock.stub!(:get).and_return(@response)
595
+ @session.event_metadata('event_json').should == resp
596
+ end
597
+ end
598
+
599
+ describe "#event_content" do
600
+ it "should call the API method event_content" do
601
+ @response.stub!(:body).and_return('content')
602
+ @response.stub!(:header).and_return('X-Dropbox-Metadata' => '{"a":"b"}')
603
+ should_receive_api_method_with_arguments @token_mock, :get, 'event_content', { :root => 'sandbox', :target_event => '1%3A2%3A3' }, @response
604
+ @session.event_content '1:2:3'
605
+ end
606
+
607
+ it "should return the content body and the X-Dropbox-Metadata header JSON" do
608
+ resp = { 'some' => { 'json' => 123 } }
609
+ body = "Content here"
610
+ @response.stub!(:body).and_return(body)
611
+ @response.should_receive(:header).once.and_return('X-Dropbox-Metadata' => resp.to_json)
612
+ @token_mock.stub!(:get).and_return(@response)
613
+
614
+ @session.event_content('1:2:3').should == [ body, resp ]
615
+ end
616
+ end
617
+
618
+ {
619
+ :account => [ :get ],
620
+ :upload => [ :post, __FILE__, 'path/here' ],
621
+ :copy => [ :post, 'source/file', 'dest/file' ],
622
+ :move => [ :post, 'source/file', 'dest/file' ],
623
+ :create_folder => [ :post, 'new/folder' ],
624
+ :metadata => [ :get, 'some/file' ],
625
+ :event_metadata => [ :get, 'some_json' ]
626
+ }.each do |meth, args|
627
+ describe meth do
628
+ before :each do
629
+ stub_for_upload_testing
630
+ @token_mock.stub!(args.first).and_return(@response)
631
+ end
632
+
633
+ it "should parse the JSON response if successful" do
634
+ @response.stub!(:body).and_return('{"test":"json"}')
635
+ @session.send(meth, *(args[1..-1]))
636
+ end
637
+
638
+ it "should raise a ParseError if the JSON is invalid" do
639
+ @response.stub!(:body).and_return('sdgsdg')
640
+ lambda { @session.send(meth, *(args[1..-1])) }.should raise_error(Dropbox::ParseError)
641
+ end
642
+
643
+ it "should raise UnsuccessfulResponseError if unsuccessful" do
644
+ @response.stub!(:kind_of?).and_return(false)
645
+ lambda { @session.send(meth, *(args[1..-1])) }.should raise_error(Dropbox::UnsuccessfulResponseError)
646
+ end
647
+ end
648
+ end
649
+
650
+ describe "#mode" do
651
+ it "should return the correct mode" do
652
+ @session.mode = :dropbox
653
+ @session.mode.should eql(:dropbox)
654
+
655
+ @session.mode = :sandbox
656
+ @session.mode.should eql(:sandbox)
657
+
658
+ @session.mode = :metadata_only
659
+ @session.mode.should eql(:metadata_only)
660
+ end
661
+
662
+ it "should be :sandbox by default" do
663
+ @session.mode.should eql(:sandbox)
664
+ end
665
+ end
666
+
667
+ describe "#mode=" do
668
+ it "set the API root" do
669
+ @session.mode = :dropbox
670
+ @token_mock.should_receive(:get).once do |url, *rest|
671
+ url.should include('/dropbox')
672
+ url.should_not include('/sandbox')
673
+ @response
674
+ end
675
+ @session.download 'file'
676
+
677
+ @session.mode = :sandbox
678
+ @token_mock.should_receive(:get).once do |url, *rest|
679
+ url.should include('/sandbox')
680
+ url.should_not include('/dropbox')
681
+ @response
682
+ end
683
+ @session.download 'file'
684
+
685
+ @session.mode = :metadata_only
686
+ @token_mock.should_receive(:get).once do |url, *rest|
687
+ url.should include('/dropbox')
688
+ url.should_not include('/sandbox')
689
+ @response
690
+ end
691
+ @session.download 'file'
692
+ end
693
+
694
+ it "should raise for invalid modes" do
695
+ lambda { @session.mode = :foo }.should raise_error(ArgumentError)
696
+ end
697
+ end
698
+
699
+ {
700
+ :account => [],
701
+ :copy => [ 'foo', 'bar' ],
702
+ :create_folder => [ 'foo' ],
703
+ :delete => [ 'foo' ],
704
+ :move => [ 'foo', 'bar' ],
705
+ :link => [ 'foo' ],
706
+ :metadata => [ 'foo'],
707
+ :download => [ 'foo' ],
708
+ :event_metadata => [ 'foo' ],
709
+ :event_content => [ 'foo' ]
710
+ }.each do |root_method, args|
711
+ describe ".#{root_method}" do
712
+ before :each do
713
+ @session = Dropbox::Session.new('foo', 'bar', :ssl => true)
714
+ @session.authorize
715
+
716
+ @token_mock.stub!(:get).and_return(@response)
717
+ @token_mock.stub!(:post).and_return(@response)
718
+ @response.stub!(:body).and_return('{"a":"b"}')
719
+ @response.stub!(:header).and_return('X-Dropbox-Metadata' => '{"a":"b"}')
720
+ end
721
+
722
+ it "should use the SSL host if :ssl => true is given to the constructor" do
723
+ Dropbox.should_receive(:api_url).once do |*args|
724
+ args.last[:ssl].should be_true
725
+ "http://www.example.com/test"
726
+ end
727
+
728
+ @session.send(root_method, *args)
729
+ end
730
+ end
731
+ end
732
+
733
+ {
734
+ :download => [ :get, 'path/to/file' ],
735
+ :copy => [ :post, 'source/file', 'dest/file' ],
736
+ :move => [ :post, 'source/file', 'dest/file' ],
737
+ :create_folder => [ :post, 'new/folder' ],
738
+ :delete => [ :post, 'some/file' ],
739
+ :link => [ :get, 'some/file' ],
740
+ :metadata => [ :get, 'some/file' ],
741
+ :event_metadata => [ :get, 'some_json' ],
742
+ :event_content => [ :get, '1:2:3' ]
743
+ }.each do |root_method, args|
744
+ describe ".#{root_method}" do
745
+ before :each do
746
+ @response.stub!(:body).and_return('{"a":"b"}')
747
+ @response.stub!(:header).and_return('X-Dropbox-Metadata' => '{"a":"b"}')
748
+ end
749
+
750
+ it "should use the dropbox root if in dropbox mode" do
751
+ @token_mock.should_receive(args.first).once do |url, *rest|
752
+ url.should_not include('sandbox')
753
+ @response
754
+ end
755
+ @session.mode = :dropbox
756
+ @session.send(root_method, *(args[1..-1]))
757
+ end
758
+
759
+ it "should use the sandbox root if in sandbox mode" do
760
+ @token_mock.should_receive(args.first).once do |url, *rest|
761
+ url.should include('sandbox')
762
+ @response
763
+ end
764
+ @session.mode = :sandbox
765
+ @session.send(root_method, *(args[1..-1]))
766
+ end
767
+
768
+ it "should use the dropbox root if in metadata mode" do
769
+ @token_mock.should_receive(args.first).once do |url, *rest|
770
+ url.should_not include('sandbox')
771
+ @response
772
+ end
773
+ @session.mode = :metadata_only
774
+ @session.send(root_method, *(args[1..-1]))
775
+ end
776
+ end
777
+ end
778
+ end