storage_room 0.1.0
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.
- data/.gitignore +22 -0
- data/History.txt +3 -0
- data/LICENSE +20 -0
- data/README.rdoc +51 -0
- data/Rakefile +50 -0
- data/TODO +9 -0
- data/VERSION +1 -0
- data/examples/authentication.rb +6 -0
- data/examples/create_resource.rb +24 -0
- data/examples/destroy_resource.rb +11 -0
- data/examples/get_collections.rb +11 -0
- data/examples/guidebooks.csv +21 -0
- data/examples/import_csv.rb +21 -0
- data/examples/search_resources.rb +13 -0
- data/examples/update_resource.rb +15 -0
- data/lib/storage_room/array.rb +64 -0
- data/lib/storage_room/attributes.rb +37 -0
- data/lib/storage_room/base.rb +56 -0
- data/lib/storage_room/embedded.rb +6 -0
- data/lib/storage_room/embeddeds/file.rb +5 -0
- data/lib/storage_room/embeddeds/location.rb +5 -0
- data/lib/storage_room/field.rb +7 -0
- data/lib/storage_room/model.rb +111 -0
- data/lib/storage_room/models/collection.rb +31 -0
- data/lib/storage_room/models/resource.rb +53 -0
- data/lib/storage_room.rb +89 -0
- data/spec/fixtures/collection.json +38 -0
- data/spec/fixtures/collections.json +42 -0
- data/spec/fixtures/validation_error.json +7 -0
- data/spec/spec_helper.rb +34 -0
- data/spec/storage_room/array_spec.rb +77 -0
- data/spec/storage_room/attributes_spec.rb +82 -0
- data/spec/storage_room/base_spec.rb +110 -0
- data/spec/storage_room/embedded_spec.rb +5 -0
- data/spec/storage_room/embeddeds/file_spec.rb +5 -0
- data/spec/storage_room/embeddeds/location_spec.rb +5 -0
- data/spec/storage_room/field_spec.rb +5 -0
- data/spec/storage_room/model_spec.rb +239 -0
- data/spec/storage_room/models/collection_spec.rb +54 -0
- data/spec/storage_room/models/resource_spec.rb +68 -0
- data/spec/storage_room_spec.rb +99 -0
- metadata +188 -0
data/lib/storage_room.rb
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
$:.unshift(File.dirname(__FILE__)) unless
|
2
|
+
$:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
|
3
|
+
|
4
|
+
begin; require 'rubygems'; rescue LoadError; end
|
5
|
+
|
6
|
+
require 'httparty'
|
7
|
+
require 'activesupport'
|
8
|
+
|
9
|
+
|
10
|
+
module StorageRoom
|
11
|
+
class AbstractMethod < RuntimeError; end
|
12
|
+
class RequestFailed < RuntimeError; end
|
13
|
+
|
14
|
+
autoload :Attributes, 'storage_room/attributes'
|
15
|
+
|
16
|
+
autoload :Base, 'storage_room/base'
|
17
|
+
autoload :Model, 'storage_room/model'
|
18
|
+
autoload :Array, 'storage_room/array'
|
19
|
+
autoload :Field, 'storage_room/field'
|
20
|
+
autoload :Embedded, 'storage_room/embedded'
|
21
|
+
|
22
|
+
autoload :Collection, 'storage_room/models/collection'
|
23
|
+
autoload :Resource, 'storage_room/models/resource'
|
24
|
+
|
25
|
+
autoload :File, 'storage_room/embeddeds/file'
|
26
|
+
autoload :Location, 'storage_room/embeddeds/location'
|
27
|
+
|
28
|
+
|
29
|
+
class << self
|
30
|
+
attr_reader :api_key
|
31
|
+
attr_reader :user_agent
|
32
|
+
attr_reader :account_id
|
33
|
+
attr_reader :ssl
|
34
|
+
attr_reader :proxy_server
|
35
|
+
attr_reader :proxy_port
|
36
|
+
|
37
|
+
def authenticate(account_id, api_key)
|
38
|
+
Base.basic_auth(api_key, 'X')
|
39
|
+
@api_key = api_key
|
40
|
+
@account_id = account_id
|
41
|
+
update_uri
|
42
|
+
end
|
43
|
+
|
44
|
+
def user_agent=(agent)
|
45
|
+
Base.headers.merge!('User-Agent' => agent)
|
46
|
+
@user_agent = agent
|
47
|
+
end
|
48
|
+
|
49
|
+
def server=(server)
|
50
|
+
@server = server
|
51
|
+
update_uri
|
52
|
+
end
|
53
|
+
|
54
|
+
def server
|
55
|
+
@server || 'api.storageroomapp.com'
|
56
|
+
end
|
57
|
+
|
58
|
+
def ssl=(ssl)
|
59
|
+
@ssl = ssl
|
60
|
+
update_uri
|
61
|
+
end
|
62
|
+
|
63
|
+
def http_proxy(server, port)
|
64
|
+
@proxy_server = server
|
65
|
+
@proxy_port = port
|
66
|
+
Base.http_proxy(server, port)
|
67
|
+
end
|
68
|
+
|
69
|
+
def update_uri
|
70
|
+
protocol = self.ssl == true ? 'https' : 'http'
|
71
|
+
|
72
|
+
Base.base_uri "#{protocol}://#{self.server}/accounts/#{self.account_id}"
|
73
|
+
end
|
74
|
+
|
75
|
+
def class_for_name(name)
|
76
|
+
if StorageRoom.const_defined?(name)
|
77
|
+
"StorageRoom::#{name}".constantize
|
78
|
+
elsif Object.const_defined?(name)
|
79
|
+
name.constantize
|
80
|
+
else
|
81
|
+
klass = Class.new(Resource)
|
82
|
+
Object.const_set(name, klass)
|
83
|
+
|
84
|
+
klass
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
{
|
2
|
+
"collection": {
|
3
|
+
"name": "Guidebooks",
|
4
|
+
"@updated_at": "2010-11-05T12:55:04Z",
|
5
|
+
"@resources_url": "http://api.storageroomapp.com/accounts/4c8fd48542507175aa00002f/collections/guidebooks/resources",
|
6
|
+
"@created_at": "2010-09-14T20:01:13Z",
|
7
|
+
"fields": [{
|
8
|
+
"name": "Title",
|
9
|
+
"required": true,
|
10
|
+
"default_value": "",
|
11
|
+
"allow_blank_choice": false,
|
12
|
+
"input_type": "text_field",
|
13
|
+
"@type": "StringField",
|
14
|
+
"hint": "",
|
15
|
+
"choices": [],
|
16
|
+
"identifier": "title"
|
17
|
+
},
|
18
|
+
{
|
19
|
+
"name": "PDF",
|
20
|
+
"required": false,
|
21
|
+
"input_type": "file",
|
22
|
+
"@type": "FileField",
|
23
|
+
"hint": "Upload a PDF file",
|
24
|
+
"identifier": "pdf"
|
25
|
+
},
|
26
|
+
{
|
27
|
+
"name": "location",
|
28
|
+
"required": false,
|
29
|
+
"input_type": "location",
|
30
|
+
"@type": "LocationField",
|
31
|
+
"hint": "",
|
32
|
+
"identifier": "location"
|
33
|
+
}],
|
34
|
+
"@type": "Collection",
|
35
|
+
"@url": "http://api.storageroomapp.com/accounts/4c8fd48542507175aa00002f/collections/guidebooks",
|
36
|
+
"identifier": "guidebooks"
|
37
|
+
}
|
38
|
+
}
|
@@ -0,0 +1,42 @@
|
|
1
|
+
{
|
2
|
+
"collections": {
|
3
|
+
"@type": "Array",
|
4
|
+
"@url": "http://api.storageroomapp.com/accounts/4c8fd48542507175aa00002f/collections",
|
5
|
+
"items": [{
|
6
|
+
"name": "Guidebooks",
|
7
|
+
"@updated_at": "2010-11-05T12:55:04Z",
|
8
|
+
"@resources_url": "http://api.storageroomapp.com/accounts/4c8fd48542507175aa00002f/collections/guidebooks/resources",
|
9
|
+
"@created_at": "2010-09-14T20:01:13Z",
|
10
|
+
"fields": [{
|
11
|
+
"name": "Title",
|
12
|
+
"required": true,
|
13
|
+
"default_value": "",
|
14
|
+
"allow_blank_choice": false,
|
15
|
+
"input_type": "text_field",
|
16
|
+
"@type": "StringField",
|
17
|
+
"hint": "",
|
18
|
+
"choices": [],
|
19
|
+
"identifier": "title"
|
20
|
+
},
|
21
|
+
{
|
22
|
+
"name": "PDF",
|
23
|
+
"required": false,
|
24
|
+
"input_type": "file",
|
25
|
+
"@type": "FileField",
|
26
|
+
"hint": "Upload a PDF file",
|
27
|
+
"identifier": "pdf"
|
28
|
+
},
|
29
|
+
{
|
30
|
+
"name": "location",
|
31
|
+
"required": false,
|
32
|
+
"input_type": "location",
|
33
|
+
"@type": "LocationField",
|
34
|
+
"hint": "",
|
35
|
+
"identifier": "location"
|
36
|
+
}],
|
37
|
+
"@type": "Collection",
|
38
|
+
"@url": "http://api.storageroomapp.com/accounts/4c8fd48542507175aa00002f/collections/guidebooks",
|
39
|
+
"identifier": "guidebooks"
|
40
|
+
}]
|
41
|
+
}
|
42
|
+
}
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
2
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
3
|
+
require 'storage_room'
|
4
|
+
require 'spec'
|
5
|
+
require 'spec/autorun'
|
6
|
+
require 'webmock/rspec'
|
7
|
+
|
8
|
+
Spec::Runner.configure do |config|
|
9
|
+
config.include WebMock::API
|
10
|
+
|
11
|
+
config.before(:each) do
|
12
|
+
StorageRoom.authenticate('USER_ID', 'APPLICATION_API_KEY')
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
def stub_url(url)
|
18
|
+
"APPLICATION_API_KEY:X@api.storageroomapp.com/accounts/USER_ID#{url}"
|
19
|
+
end
|
20
|
+
|
21
|
+
def fixture_file(name)
|
22
|
+
path = File.expand_path("#{File.dirname(__FILE__)}/fixtures/#{name}")
|
23
|
+
File.read(path)
|
24
|
+
end
|
25
|
+
|
26
|
+
def mock_httparty(code)
|
27
|
+
httparty = mock('httparty')
|
28
|
+
response = mock('response')
|
29
|
+
response.stub(:code).and_return(code.to_s)
|
30
|
+
|
31
|
+
httparty.stub(:response).and_return(response)
|
32
|
+
|
33
|
+
httparty
|
34
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
describe StorageRoom::Array do
|
4
|
+
context "Class" do
|
5
|
+
context "Configuration" do
|
6
|
+
|
7
|
+
end
|
8
|
+
|
9
|
+
context "Methods" do
|
10
|
+
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
context "Instance" do
|
15
|
+
before(:each) do
|
16
|
+
@array = StorageRoom::Array.new
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "#initialize" do
|
20
|
+
it "should set items" do
|
21
|
+
@array.items.should == []
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "#set_from_api" do
|
26
|
+
before(:each) do
|
27
|
+
@hash = {'@page' => 1, 'items' => [{'one' => 1, '@type' => 'Guidebook'}, {'two' => 2, '@type' => 'Guidebook'}]}
|
28
|
+
@array.set_from_api(@hash)
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should set meta data" do
|
32
|
+
@array['@page'].should == 1
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should set items" do
|
36
|
+
@array.items.should have(2).items
|
37
|
+
@array.items[0].should be_an_instance_of(Guidebook)
|
38
|
+
@array.items[0][:one].should == 1
|
39
|
+
@array.items[1].should be_an_instance_of(Guidebook)
|
40
|
+
@array.items[1][:two].should == 2
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe "#reset!" do
|
45
|
+
it "should reset" do
|
46
|
+
@array.reset!
|
47
|
+
@array.items.should == []
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe "#load_next_page!" do
|
52
|
+
it "should not load when not present" do
|
53
|
+
@array.load_next_page!.should be_false
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should load when present" do
|
57
|
+
@array[:@next_page] = "url"
|
58
|
+
@array.stub(:reload)
|
59
|
+
@array.should_receive(:reload)
|
60
|
+
@array.load_next_page!.should be_true
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe "#load_previous_page!" do
|
65
|
+
it "should not load when not present" do
|
66
|
+
@array.load_previous_page!.should be_false
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should load when present" do
|
70
|
+
@array[:@previous_page] = "url"
|
71
|
+
@array.stub(:reload)
|
72
|
+
@array.should_receive(:reload)
|
73
|
+
@array.load_previous_page!.should be_true
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
module StorageRoom
|
4
|
+
class TestAttributes
|
5
|
+
include Attributes
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
describe StorageRoom::TestAttributes do
|
10
|
+
|
11
|
+
context "Instance" do
|
12
|
+
before(:each) do
|
13
|
+
@test = StorageRoom::TestAttributes.new(:test => 1, :@attr => 2)
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "#initialize" do
|
17
|
+
it "should set attributes" do
|
18
|
+
@test[:test].should == 1
|
19
|
+
@test[:@attr].should == 2
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "#set_from_api" do
|
24
|
+
before(:each) do
|
25
|
+
@test.set_from_api(:test2 => 3)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should reset attributes" do
|
29
|
+
@test[:test].should be_nil
|
30
|
+
@test[:@attr].should be_nil
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should set new attributes" do
|
34
|
+
@test[:test2].should == 3
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe "#[]" do
|
39
|
+
it "should get attribute" do
|
40
|
+
@test[:test].should == 1
|
41
|
+
@test[:@attr].should == 2
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe "#[]=" do
|
46
|
+
it "should set attribute" do
|
47
|
+
@test[:test3] = 5
|
48
|
+
@test[:test3].should == 5
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe "#attributes" do
|
53
|
+
it "should return existing attributes" do
|
54
|
+
@test.attributes[:test].should == 1
|
55
|
+
@test.attributes['test'].should == 1
|
56
|
+
@test.attributes[:@attr].should == 2
|
57
|
+
@test.attributes['@attr'].should == 2
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe "#attributes=" do
|
62
|
+
before(:each) do
|
63
|
+
@test.attributes = {:new => 8, :test => 0}
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should set attributes" do
|
67
|
+
@test.attributes[:new].should == 8
|
68
|
+
@test.attributes[:test].should == 0
|
69
|
+
@test.attributes[:@attr].should == 2
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
describe "#reset!" do
|
74
|
+
it "should reset" do
|
75
|
+
@test.reset!
|
76
|
+
@test.attributes.should == {}
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
describe StorageRoom::Base do
|
4
|
+
context "Class" do
|
5
|
+
context "Configuration" do
|
6
|
+
describe "Headers" do
|
7
|
+
it "should have User-Agent" do
|
8
|
+
StorageRoom::Base.headers['User-Agent'].should be_present
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should set Content Type" do
|
12
|
+
StorageRoom::Base.headers['Content-Type'].should == 'application/json'
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should set Accept" do
|
16
|
+
StorageRoom::Base.headers['Accept'].should == 'application/json'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should not have base_uri" do
|
21
|
+
StorageRoom::Base.base_uri.should be_present
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should have format" do
|
25
|
+
StorageRoom::Base.default_options[:format].should == :json
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context "Methods" do
|
30
|
+
describe "#load" do
|
31
|
+
it "should load" do
|
32
|
+
stub_request(:get, stub_url('/collections')).to_return(:body => fixture_file('collections.json'), :status => 200)
|
33
|
+
|
34
|
+
array = StorageRoom::Array.load('/collections')
|
35
|
+
array[:@type].should == 'Array'
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should raise on error" do
|
39
|
+
stub_request(:get, stub_url('/collections')).to_return(:status => 500)
|
40
|
+
|
41
|
+
lambda {
|
42
|
+
StorageRoom::Array.load('/collections')
|
43
|
+
}.should raise_error(StorageRoom::RequestFailed)
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe "#handle_critical_response_errors" do
|
49
|
+
it "should handle no error" do
|
50
|
+
httparty = mock_httparty(200)
|
51
|
+
StorageRoom::Base.handle_critical_response_errors(httparty).should be_true
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should raise error" do
|
55
|
+
lambda {
|
56
|
+
StorageRoom::Base.handle_critical_response_errors(mock_httparty(500))
|
57
|
+
}.should raise_error(StorageRoom::RequestFailed)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe "#create_from_api" do
|
62
|
+
it "should create array" do
|
63
|
+
hash = {'@type' => 'Array', 'items' => []}
|
64
|
+
result = StorageRoom::Base.create_from_api(hash)
|
65
|
+
result.should be_an_instance_of(StorageRoom::Array)
|
66
|
+
result[:@type].should == 'Array'
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should create collection" do
|
70
|
+
hash = {'@type' => 'Collection', 'name' => 'Guidebook'}
|
71
|
+
result = StorageRoom::Base.create_from_api(hash)
|
72
|
+
result.should be_an_instance_of(StorageRoom::Collection)
|
73
|
+
result[:name].should == 'Guidebook'
|
74
|
+
end
|
75
|
+
|
76
|
+
it "should create resource" do
|
77
|
+
hash = {'@type' => 'Guidebook', 'title' => 'Something'}
|
78
|
+
result = StorageRoom::Base.create_from_api(hash)
|
79
|
+
result.should be_an_instance_of(Guidebook)
|
80
|
+
result[:title].should == 'Something'
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
describe "#meta_data?" do
|
85
|
+
it "should detect" do
|
86
|
+
StorageRoom::Base.meta_data?('@test').should be_true
|
87
|
+
StorageRoom::Base.meta_data?('test').should be_false
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
context "Instance" do
|
95
|
+
before(:each) do
|
96
|
+
@base = StorageRoom::Base.new(:test => 1, :@attr => 2)
|
97
|
+
end
|
98
|
+
|
99
|
+
describe "#url" do
|
100
|
+
it "should return url" do
|
101
|
+
@base.url.should be_nil
|
102
|
+
@base[:@url] = 'url'
|
103
|
+
@base.url.should == 'url'
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|