box-api 0.1.6
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +40 -0
- data/LICENSE.txt +202 -0
- data/README.md +23 -0
- data/Rakefile +6 -0
- data/box-api.gemspec +21 -0
- data/examples/app_data.yml +6 -0
- data/examples/files.rb +36 -0
- data/examples/login.rb +57 -0
- data/lib/box-api.rb +16 -0
- data/lib/box/account.rb +108 -0
- data/lib/box/api.rb +140 -0
- data/lib/box/api/exceptions.rb +75 -0
- data/lib/box/file.rb +37 -0
- data/lib/box/folder.rb +140 -0
- data/lib/box/item.rb +127 -0
- data/spec/account_spec.rb +43 -0
- data/spec/api_spec.rb +19 -0
- data/spec/file_spec.rb +105 -0
- data/spec/folder_spec.rb +117 -0
- data/spec/helper/account.rb +17 -0
- data/spec/helper/account.yml +3 -0
- data/spec/helper/fake_tree.rb +101 -0
- data/spec/item_spec.rb +51 -0
- metadata +139 -0
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'helper/account'
|
2
|
+
|
3
|
+
require 'box/api'
|
4
|
+
require 'box/account'
|
5
|
+
|
6
|
+
describe Box::Account do
|
7
|
+
describe "without authorization" do
|
8
|
+
before(:each) do
|
9
|
+
@account = get_account(false)
|
10
|
+
end
|
11
|
+
|
12
|
+
it "gets a ticket" do
|
13
|
+
@account.ticket.should_not == nil
|
14
|
+
end
|
15
|
+
|
16
|
+
it "fails to authorize without auth token" do
|
17
|
+
@account.authorize.should == false
|
18
|
+
end
|
19
|
+
|
20
|
+
it "authorizes using auth token" do
|
21
|
+
@account.authorize(ACCOUNT['auth_token']).should == true
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "with authorization" do
|
26
|
+
before(:each) do
|
27
|
+
@account = get_account
|
28
|
+
end
|
29
|
+
|
30
|
+
# TODO: We need a way to reauthorize automatically, because logout resets the auth token
|
31
|
+
#it "can logout" do
|
32
|
+
# @account.logout.should == true
|
33
|
+
#end
|
34
|
+
|
35
|
+
it "gets the root folder" do
|
36
|
+
@account.root.id.should == 0
|
37
|
+
end
|
38
|
+
|
39
|
+
it "caches the root folder" do
|
40
|
+
@account.root.should be @account.root
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
data/spec/api_spec.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'box/api'
|
2
|
+
|
3
|
+
describe Box::Api do
|
4
|
+
it "fails without api key" do
|
5
|
+
lambda { Box::Api.new('').get_ticket }.should raise_error
|
6
|
+
end
|
7
|
+
|
8
|
+
it "fails with invalid api key" do
|
9
|
+
lambda { Box::Api.new('invalidapikey').get_ticket }.should raise_error
|
10
|
+
end
|
11
|
+
|
12
|
+
it "fails with invalid url" do
|
13
|
+
lambda { Box::Api.new('invalidapikey', 'http://google.com').get_ticket }.should raise_error
|
14
|
+
end
|
15
|
+
|
16
|
+
it "fails with invalid version" do
|
17
|
+
lambda { Box::Api.new('invalidapikey', 'https://box.net', 'https://upload.box.net', '3.14').get_ticket }.should raise_error
|
18
|
+
end
|
19
|
+
end
|
data/spec/file_spec.rb
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
require 'helper/account'
|
2
|
+
|
3
|
+
require 'box/api'
|
4
|
+
require 'box/account'
|
5
|
+
require 'box/file'
|
6
|
+
require 'box/folder'
|
7
|
+
|
8
|
+
describe Box::File do
|
9
|
+
describe "operations" do
|
10
|
+
before(:all) do
|
11
|
+
@root = get_root
|
12
|
+
spec = @root.find(:name => 'rspec folder', :type => 'folder', :recursive => false).first
|
13
|
+
spec.delete if spec
|
14
|
+
end
|
15
|
+
|
16
|
+
before(:each) do
|
17
|
+
@hello_file = 'dummy.test'
|
18
|
+
File.open(@hello_file, 'w') { |f| f.write("Hello World!") }
|
19
|
+
|
20
|
+
@vegetables = 'veg.test'
|
21
|
+
File.open(@vegetables, 'w') { |f| f.write("banana, orange, avachokado") }
|
22
|
+
|
23
|
+
@test_root = @root.create('rspec folder')
|
24
|
+
@dummy = @test_root.upload(@hello_file)
|
25
|
+
end
|
26
|
+
|
27
|
+
after(:each) do
|
28
|
+
File.delete(@hello_file)
|
29
|
+
File.delete(@vegetables)
|
30
|
+
|
31
|
+
@test_root.delete
|
32
|
+
end
|
33
|
+
|
34
|
+
it "gets file info" do
|
35
|
+
@dummy.name.should_not == nil
|
36
|
+
end
|
37
|
+
|
38
|
+
it "lazy-loads file info" do
|
39
|
+
@dummy.data['sha1'].should == nil
|
40
|
+
@dummy.sha1.should_not == nil
|
41
|
+
@dummy.data['sha1'].should_not == nil
|
42
|
+
end
|
43
|
+
|
44
|
+
it "uploads a new file" do
|
45
|
+
@dummy.parent.should be @test_root
|
46
|
+
@dummy.name.should == 'dummy.test'
|
47
|
+
end
|
48
|
+
|
49
|
+
it "uploads a copy" do
|
50
|
+
file = @dummy.upload_copy(@vegetables)
|
51
|
+
|
52
|
+
file.name.should == 'dummy (1).test'
|
53
|
+
file.parent.should be @test_root
|
54
|
+
file.sha1.should_not == @dummy.sha1
|
55
|
+
|
56
|
+
@test_root.files.should have(2).things
|
57
|
+
end
|
58
|
+
|
59
|
+
it "overwrites a file" do
|
60
|
+
temp = @dummy.sha1
|
61
|
+
@dummy.upload_overwrite(@vegetables)
|
62
|
+
|
63
|
+
@dummy.parent.should be @test_root
|
64
|
+
@dummy.name.should == 'dummy.test'
|
65
|
+
@dummy.sha1.should_not == temp
|
66
|
+
|
67
|
+
@test_root.files.should have(1).things
|
68
|
+
end
|
69
|
+
|
70
|
+
it "downloads a file" do
|
71
|
+
@dummy.download('dummy.down')
|
72
|
+
`diff #{ @hello_file } dummy.down`.should == ""
|
73
|
+
|
74
|
+
File.delete('dummy.down')
|
75
|
+
end
|
76
|
+
|
77
|
+
it "moves a file" do
|
78
|
+
@test_temp = @test_root.create('temp')
|
79
|
+
|
80
|
+
@dummy.move(@test_temp)
|
81
|
+
@dummy.parent.should be @test_temp
|
82
|
+
end
|
83
|
+
|
84
|
+
it "copies a file" do
|
85
|
+
@test_temp = @test_root.create('temp')
|
86
|
+
clone = @dummy.copy(@test_temp)
|
87
|
+
|
88
|
+
clone.parent.should be @test_temp
|
89
|
+
clone.name.should == @dummy.name
|
90
|
+
clone.should_not be @dummy
|
91
|
+
end
|
92
|
+
|
93
|
+
it "renames a file" do
|
94
|
+
@dummy.rename('bandito.txt')
|
95
|
+
@dummy.name.should == 'bandito.txt'
|
96
|
+
end
|
97
|
+
|
98
|
+
it "deletes a folder" do
|
99
|
+
@dummy.delete
|
100
|
+
|
101
|
+
@dummy.parent.should be nil
|
102
|
+
@test_root.files.should have(0).things
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
data/spec/folder_spec.rb
ADDED
@@ -0,0 +1,117 @@
|
|
1
|
+
require 'helper/account'
|
2
|
+
require 'helper/fake_tree'
|
3
|
+
|
4
|
+
require 'box/api'
|
5
|
+
require 'box/account'
|
6
|
+
require 'box/folder'
|
7
|
+
|
8
|
+
describe Box::Folder do
|
9
|
+
context "with api" do
|
10
|
+
before(:all) do
|
11
|
+
@root = get_root
|
12
|
+
spec = @root.find(:name => 'rspec folder', :type => 'folder', :recursive => false).first
|
13
|
+
spec.delete if spec
|
14
|
+
end
|
15
|
+
|
16
|
+
before(:each) do
|
17
|
+
@test_root = @root.create('rspec folder')
|
18
|
+
@test_temp = @test_root.create('temp')
|
19
|
+
|
20
|
+
@dummy = @test_root.create('dummy')
|
21
|
+
end
|
22
|
+
|
23
|
+
after(:each) do
|
24
|
+
@test_root.delete
|
25
|
+
end
|
26
|
+
|
27
|
+
it "creates a new folder" do
|
28
|
+
@dummy.parent.should be @test_root
|
29
|
+
@dummy.name.should == 'dummy'
|
30
|
+
end
|
31
|
+
|
32
|
+
it "moves a folder" do
|
33
|
+
@dummy.move(@test_temp)
|
34
|
+
@dummy.parent.should be @test_temp
|
35
|
+
end
|
36
|
+
|
37
|
+
it "renames a folder" do
|
38
|
+
@dummy.rename('bandito')
|
39
|
+
@dummy.name.should == 'bandito'
|
40
|
+
end
|
41
|
+
|
42
|
+
it "deletes a folder" do
|
43
|
+
@dummy.create('todelete').delete
|
44
|
+
@dummy.folders.should have(0).items
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context "using fake tree" do
|
49
|
+
before(:each) do
|
50
|
+
api = double("Api")
|
51
|
+
api.stub("get_account_tree") do |*args|
|
52
|
+
fake_tree
|
53
|
+
end
|
54
|
+
|
55
|
+
@root = Box::Folder.new(api, nil, :id => 0)
|
56
|
+
end
|
57
|
+
|
58
|
+
describe "#find" do
|
59
|
+
describe "single result" do
|
60
|
+
it "finds existing item" do
|
61
|
+
file = @root.find(:name => 'expected.1.swf').first
|
62
|
+
file.id.should == '61679540'
|
63
|
+
file.name.should == 'expected.1.swf'
|
64
|
+
end
|
65
|
+
|
66
|
+
it "finds non-existant file" do
|
67
|
+
file = @root.find(:name => 'notfound.png').first
|
68
|
+
file.should be nil
|
69
|
+
end
|
70
|
+
|
71
|
+
it "finds specified format" do
|
72
|
+
folder = @root.find(:name => 'tests', :type => 'folder').first
|
73
|
+
folder.id.should == '7065552'
|
74
|
+
folder.name.should == 'tests'
|
75
|
+
|
76
|
+
file = @root.find(:name => 'tests', :type => 'file').first
|
77
|
+
file.should be nil
|
78
|
+
end
|
79
|
+
|
80
|
+
it "finds specified criteria" do
|
81
|
+
file = @root.find(:type => 'file', :sha1 => 'f7379ffe883fdc355fbe47e8a4b3073f21ac0f6d').first
|
82
|
+
file.id.should == '61669270'
|
83
|
+
file.name.should == 'file.pdf'
|
84
|
+
end
|
85
|
+
|
86
|
+
it "obeys recursive flag" do
|
87
|
+
file = @root.find(:type => 'file', :sha1 => 'f7379ffe883fdc355fbe47e8a4b3073f21ac0f6d', :recursive => false).first
|
88
|
+
file.should == nil
|
89
|
+
end
|
90
|
+
|
91
|
+
it "finds multiple criteria" do
|
92
|
+
file = @root.find(:updated => 1304959908, :size => 20372).first
|
93
|
+
file.id.should == '61679546'
|
94
|
+
file.name.should == 'expected.3.swf'
|
95
|
+
end
|
96
|
+
|
97
|
+
it "requires both criteria" do
|
98
|
+
file = @root.find(:updated => 1304, :size => 20372).first
|
99
|
+
file.should be nil
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
describe "multiple results" do
|
104
|
+
it "finds multiple files" do
|
105
|
+
items = @root.find(:name => 'expected.1.swf')
|
106
|
+
items.should have(2).items
|
107
|
+
end
|
108
|
+
|
109
|
+
it "finds all files" do
|
110
|
+
files = @root.find(:type => 'file')
|
111
|
+
files.should have(9).items
|
112
|
+
files.first.name.should == 'file.pdf'
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
ACCOUNT = YAML.load_file(File.dirname(__FILE__) + '/account.yml')
|
4
|
+
|
5
|
+
def get_api
|
6
|
+
Box::Api.new(ACCOUNT['api_key'])
|
7
|
+
end
|
8
|
+
|
9
|
+
def get_account(auth = true)
|
10
|
+
Box::Account.new(get_api).tap do |account|
|
11
|
+
account.authorize(ACCOUNT['auth_token']) if auth
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def get_root
|
16
|
+
get_account.root
|
17
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
def fake_tree
|
2
|
+
{"status"=>"listing_ok",
|
3
|
+
"tree"=>
|
4
|
+
{"folder"=>
|
5
|
+
{"folders"=>
|
6
|
+
{"folder"=>
|
7
|
+
{"folders"=>
|
8
|
+
{"folder"=>
|
9
|
+
[{"folders"=>
|
10
|
+
{"folder"=>
|
11
|
+
[{"folders"=>
|
12
|
+
{"folder"=>
|
13
|
+
{"files"=>
|
14
|
+
{"file"=>
|
15
|
+
{"id"=>"61679540",
|
16
|
+
"file_name"=>"expected.1.swf",
|
17
|
+
"shared"=>"0",
|
18
|
+
"sha1"=>"9be7a98f26158401e9a9403c8a71bb690bb22165",
|
19
|
+
"created"=>"1304953733",
|
20
|
+
"updated"=>"1304955616",
|
21
|
+
"size"=>"110711"}},
|
22
|
+
"id"=>"7068024",
|
23
|
+
"name"=>"swf"}},
|
24
|
+
"files"=>
|
25
|
+
{"file"=>
|
26
|
+
{"id"=>"61669156",
|
27
|
+
"file_name"=>"file.pdf",
|
28
|
+
"shared"=>"0",
|
29
|
+
"sha1"=>"83d4bb7067fed70489992f1440f3404693880b33",
|
30
|
+
"created"=>"1304018516",
|
31
|
+
"updated"=>"1304716801",
|
32
|
+
"size"=>"466028"}},
|
33
|
+
"id"=>"7065564",
|
34
|
+
"name"=>"about stacks"},
|
35
|
+
{"folders"=>
|
36
|
+
{"folder"=>
|
37
|
+
{"files"=>
|
38
|
+
{"file"=>
|
39
|
+
[{"id"=>"61679542",
|
40
|
+
"file_name"=>"expected.1.swf",
|
41
|
+
"shared"=>"0",
|
42
|
+
"sha1"=>"1cf19ac8a82365af82f45c35a2be54713c1e3b25",
|
43
|
+
"created"=>"1304959905",
|
44
|
+
"updated"=>"1304959905",
|
45
|
+
"size"=>"114916"},
|
46
|
+
{"id"=>"61679544",
|
47
|
+
"file_name"=>"expected.2.swf",
|
48
|
+
"shared"=>"0",
|
49
|
+
"sha1"=>"29013acff9ce76ce8f816f0d62ac2d95c38f764c",
|
50
|
+
"created"=>"1305128586",
|
51
|
+
"updated"=>"1305128586",
|
52
|
+
"size"=>"126916"},
|
53
|
+
{"id"=>"61679546",
|
54
|
+
"file_name"=>"expected.3.swf",
|
55
|
+
"shared"=>"0",
|
56
|
+
"sha1"=>"5d7f4cd8a07d2040dce3a2cb9993f999f4d684fa",
|
57
|
+
"created"=>"1304959908",
|
58
|
+
"updated"=>"1304959908",
|
59
|
+
"size"=>"20372"},
|
60
|
+
{"id"=>"61679548",
|
61
|
+
"file_name"=>"expected.4.swf",
|
62
|
+
"shared"=>"0",
|
63
|
+
"sha1"=>"74c049b73ebf2a3b5d54e3aed7bf78551264f384",
|
64
|
+
"created"=>"1304959910",
|
65
|
+
"updated"=>"1304959910",
|
66
|
+
"size"=>"12944"},
|
67
|
+
{"id"=>"61679550",
|
68
|
+
"file_name"=>"expected.5.swf",
|
69
|
+
"shared"=>"0",
|
70
|
+
"sha1"=>"740ebf821825c69d0b45ff92374ebbfa39a70b14",
|
71
|
+
"created"=>"1304959911",
|
72
|
+
"updated"=>"1304959911",
|
73
|
+
"size"=>"6346"},
|
74
|
+
{"id"=>"61679552",
|
75
|
+
"file_name"=>"expected.6.swf",
|
76
|
+
"shared"=>"0",
|
77
|
+
"sha1"=>"e7d9bc6ae3275824e9381c90b1ba10b9819b66c6",
|
78
|
+
"created"=>"1304959913",
|
79
|
+
"updated"=>"1304959913",
|
80
|
+
"size"=>"25704"}]},
|
81
|
+
"id"=>"7068026",
|
82
|
+
"name"=>"swf"}},
|
83
|
+
"files"=>
|
84
|
+
{"file"=>
|
85
|
+
{"id"=>"61669270",
|
86
|
+
"file_name"=>"file.pdf",
|
87
|
+
"shared"=>"0",
|
88
|
+
"sha1"=>"f7379ffe883fdc355fbe47e8a4b3073f21ac0f6d",
|
89
|
+
"created"=>"1304110450",
|
90
|
+
"updated"=>"1304372897",
|
91
|
+
"size"=>"337768"}},
|
92
|
+
"id"=>"7065566",
|
93
|
+
"name"=>"breaks thumbnail"}]},
|
94
|
+
"id"=>"7065562",
|
95
|
+
"name"=>"pdf"},
|
96
|
+
{"id"=>"7095826", "name"=>"empty"}]},
|
97
|
+
"id"=>"7065552",
|
98
|
+
"name"=>"tests"}},
|
99
|
+
"id"=>"0",
|
100
|
+
"name"=>""}}}
|
101
|
+
end
|
data/spec/item_spec.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'box/item'
|
2
|
+
|
3
|
+
describe Box::Item do
|
4
|
+
class Fake < Box::Item
|
5
|
+
def self.type; "fake"; end
|
6
|
+
def get_info(*args); { :lol => 'fake' }; end
|
7
|
+
end
|
8
|
+
|
9
|
+
def fake(options = {})
|
10
|
+
Fake.new(nil, nil, options)
|
11
|
+
end
|
12
|
+
|
13
|
+
it "has info accessors" do
|
14
|
+
item = fake(:name => 'myname', :philip => 'king')
|
15
|
+
item.name.should == 'myname'
|
16
|
+
item.philip.should == 'king'
|
17
|
+
end
|
18
|
+
|
19
|
+
it "registers type correctly" do
|
20
|
+
item = fake
|
21
|
+
item.type.should == 'fake'
|
22
|
+
item.types.should == 'fakes'
|
23
|
+
end
|
24
|
+
|
25
|
+
it "lazy-loads info" do
|
26
|
+
item = fake
|
27
|
+
item.data['lol'].should == nil
|
28
|
+
item.lol.should == 'fake'
|
29
|
+
item.data['lol'].should == 'fake'
|
30
|
+
end
|
31
|
+
|
32
|
+
it "trims unneeded attribute names" do
|
33
|
+
item = fake(:fake_name => 'myname2', :fake_philip => 'king2', :file_name => 'nottrim')
|
34
|
+
item.name.should == 'myname2'
|
35
|
+
lambda { item.fake_name }.should raise_error
|
36
|
+
item.philip.should == 'king2'
|
37
|
+
item.file_name.should == 'nottrim'
|
38
|
+
end
|
39
|
+
|
40
|
+
it "uses the right path" do
|
41
|
+
parent = fake(:name => 'my', :fakes => [])
|
42
|
+
item = fake(:name => 'path')
|
43
|
+
|
44
|
+
parent.path.should == "my"
|
45
|
+
item.path.should == "path"
|
46
|
+
|
47
|
+
item.parent = parent
|
48
|
+
parent.path.should == "my"
|
49
|
+
item.path.should == "my/path"
|
50
|
+
end
|
51
|
+
end
|