api-client 1.6.1 → 1.7.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +4 -0
- data/README.md +11 -2
- data/lib/api-client/base.rb +35 -9
- data/lib/api-client/dispatcher.rb +1 -1
- data/lib/api-client/dispatcher/net-http.rb +2 -1
- data/lib/api-client/parser.rb +2 -4
- data/lib/api-client/version.rb +1 -1
- data/spec/api-client/base_spec.rb +30 -0
- data/spec/api-client/parser_spec.rb +13 -30
- data/spec/spec_helper.rb +7 -1
- metadata +4 -4
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -57,8 +57,17 @@ class Admin < ApiClient::Base
|
|
57
57
|
end
|
58
58
|
```
|
59
59
|
|
60
|
+
It can handle associations. It will automatically instantiate an association for you if properly setted like below:
|
61
|
+
|
62
|
+
```ruby
|
63
|
+
class Person < ApiClient::Base
|
64
|
+
self.associations = { :houses => "House", :cars => "Car" }
|
65
|
+
```
|
66
|
+
|
67
|
+
This code will create a setter and a getter for houses and cars and initialize the respective class inside the setter.
|
68
|
+
|
60
69
|
## TODO
|
61
|
-
* Add
|
70
|
+
* Add support for parallel requests
|
62
71
|
* Add more Response Handlers
|
63
72
|
|
64
73
|
## Contributing
|
@@ -67,4 +76,4 @@ end
|
|
67
76
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
68
77
|
3. Commit your changes (`git commit -am 'Added some feature'`)
|
69
78
|
4. Push to the branch (`git push origin my-new-feature`)
|
70
|
-
5. Create new Pull Request
|
79
|
+
5. Create new Pull Request
|
data/lib/api-client/base.rb
CHANGED
@@ -12,16 +12,26 @@ module ApiClient
|
|
12
12
|
include ActiveModel::Conversion
|
13
13
|
extend ActiveModel::Naming
|
14
14
|
|
15
|
+
# @return [Hash] the request response.
|
16
|
+
attr_accessor :response
|
17
|
+
|
15
18
|
# Initialize an object based on a hash of attributes.
|
16
19
|
#
|
17
20
|
# @param [Hash] attributes object attributes.
|
18
21
|
# @return [Base] the object initialized.
|
19
22
|
def initialize(attributes = {})
|
20
23
|
attributes.each do |name, value|
|
21
|
-
send("#{name}=", value)
|
24
|
+
send("#{name.to_s}=", value)
|
22
25
|
end
|
23
26
|
end
|
24
27
|
|
28
|
+
# Return if a object is persisted on the database or not.
|
29
|
+
#
|
30
|
+
# @return [False] always return false.
|
31
|
+
def persisted?
|
32
|
+
false
|
33
|
+
end
|
34
|
+
|
25
35
|
# Return the Remote Object Name.
|
26
36
|
#
|
27
37
|
# @return [String] a string with the remote object class name.
|
@@ -36,11 +46,24 @@ module ApiClient
|
|
36
46
|
@remote_object = remote_object
|
37
47
|
end
|
38
48
|
|
39
|
-
#
|
49
|
+
# Set methods to initialize associated objects.
|
40
50
|
#
|
41
|
-
# @
|
42
|
-
def
|
43
|
-
|
51
|
+
# @param [Hash] association classes.
|
52
|
+
def self.associations(associations = {})
|
53
|
+
associations.each do |association, class_name|
|
54
|
+
class_eval <<-EVAL
|
55
|
+
def #{association.to_s}=(attributes = {})
|
56
|
+
@association = #{class_name.constantize}.new(attributes)
|
57
|
+
end
|
58
|
+
def #{association.to_s}
|
59
|
+
@association
|
60
|
+
end
|
61
|
+
EVAL
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
class << self
|
66
|
+
alias_method :association, :associations
|
44
67
|
end
|
45
68
|
|
46
69
|
# Return the hash of errors if existent, otherwise instantiate a new ApiClient::Errors object with self.
|
@@ -52,7 +75,7 @@ module ApiClient
|
|
52
75
|
|
53
76
|
# Set the hash of errors, making keys symbolic.
|
54
77
|
#
|
55
|
-
# @param [Hash] errors of the object
|
78
|
+
# @param [Hash] errors of the object.
|
56
79
|
def errors=(errs = {})
|
57
80
|
@errors = Errors.new(self)
|
58
81
|
@errors.add_errors(Hash[errs.map{|(key,value)| [key.to_sym,value]}])
|
@@ -61,9 +84,12 @@ module ApiClient
|
|
61
84
|
protected
|
62
85
|
|
63
86
|
def self.method_missing(method, *args)
|
64
|
-
|
65
|
-
|
66
|
-
|
87
|
+
@response = Parser.response(Dispatcher.send(method, *args))
|
88
|
+
case true
|
89
|
+
when @response.key?(remote_object) then return new(@response[remote_object].merge(:response => @response))
|
90
|
+
when @response.key?(remote_object.pluralize) then return @response[remote_object.pluralize].map { |a| new(a.merge(:response => @response)) }
|
91
|
+
else return new(@response.merge(:response => @response))
|
92
|
+
end
|
67
93
|
end
|
68
94
|
end
|
69
95
|
end
|
@@ -60,6 +60,7 @@ module ApiClient::Dispatcher::NetHttp
|
|
60
60
|
|
61
61
|
def self.initialize_connection(url = '')
|
62
62
|
@uri = URI(url)
|
63
|
+
@uri.path = "/" if @uri.path.blank?
|
63
64
|
@http = Net::HTTP.new(@uri.host, @uri.port)
|
64
65
|
end
|
65
66
|
|
@@ -70,4 +71,4 @@ module ApiClient::Dispatcher::NetHttp
|
|
70
71
|
raise ApiClient::Exceptions::ConnectionRefused
|
71
72
|
end
|
72
73
|
end
|
73
|
-
end
|
74
|
+
end
|
data/lib/api-client/parser.rb
CHANGED
@@ -4,12 +4,10 @@ module ApiClient::Parser
|
|
4
4
|
#
|
5
5
|
# @param [HTTP] response HTTP object for the request.
|
6
6
|
# @return [Array] the code and the body parsed.
|
7
|
-
def self.response(response
|
7
|
+
def self.response(response)
|
8
8
|
raise_exception(response.code)
|
9
9
|
begin
|
10
10
|
object = JSON.parse(response.body)
|
11
|
-
object = object[remote_object] if object.key?(remote_object)
|
12
|
-
object = object[remote_object.pluralize] if object.key?(remote_object.pluralize)
|
13
11
|
rescue JSON::ParserError, TypeError
|
14
12
|
object = {}
|
15
13
|
end
|
@@ -29,4 +27,4 @@ module ApiClient::Parser
|
|
29
27
|
else return
|
30
28
|
end
|
31
29
|
end
|
32
|
-
end
|
30
|
+
end
|
data/lib/api-client/version.rb
CHANGED
@@ -43,6 +43,8 @@ describe ApiClient::Base do
|
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
46
|
+
describe
|
47
|
+
|
46
48
|
describe "#errors" do
|
47
49
|
context "when @errors is not nil" do
|
48
50
|
before :each do
|
@@ -65,6 +67,20 @@ describe ApiClient::Base do
|
|
65
67
|
end
|
66
68
|
end
|
67
69
|
|
70
|
+
describe "#associations" do
|
71
|
+
before :each do
|
72
|
+
@post = Post.new({:a => "a", :writer => {:b => "b"}})
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should instantiate a new instance of the association" do
|
76
|
+
@post.writer.should be_an_instance_of(User)
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should create a setter and a getter for the associations" do
|
80
|
+
@post.writer.b.should == "b"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
68
84
|
describe "#errors=" do
|
69
85
|
before :each do
|
70
86
|
@user = User.new(:errors => { "a" => "message", "b" => "message" })
|
@@ -74,4 +90,18 @@ describe ApiClient::Base do
|
|
74
90
|
@user.errors.messages.should == { :a => %w(message), :b => %w(message) }
|
75
91
|
end
|
76
92
|
end
|
93
|
+
|
94
|
+
describe "requests" do
|
95
|
+
before :each do
|
96
|
+
stub_request(:any, "http://api.example.com").to_return(:body => {"a" => "b"}.to_json)
|
97
|
+
end
|
98
|
+
|
99
|
+
it "should return a new instance" do
|
100
|
+
User.get("http://api.example.com").should be_an_instance_of(User)
|
101
|
+
end
|
102
|
+
|
103
|
+
it "should set the response on the instance" do
|
104
|
+
User.get("http://api.example.com").response.should == {"a" => "b"}
|
105
|
+
end
|
106
|
+
end
|
77
107
|
end
|
@@ -2,31 +2,14 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe ApiClient::Parser do
|
4
4
|
describe "#response" do
|
5
|
-
before :each do
|
6
|
-
@remote_object = ApiClient::Base.remote_object
|
7
|
-
end
|
8
|
-
|
9
5
|
context "with a valid json response" do
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
@response = ApiClient::Dispatcher.post('http://api.example.com/user/5', {}, {})
|
14
|
-
end
|
15
|
-
|
16
|
-
it "should return the response code and the body parsed" do
|
17
|
-
ApiClient::Parser.response(@response, @remote_object).should == { "a" => "b" }
|
18
|
-
end
|
6
|
+
before :each do
|
7
|
+
stub_request(:post, "http://api.example.com/user/5").to_return(:body => {:base => { :a => :b } }.to_json, :status => "201")
|
8
|
+
@response = ApiClient::Dispatcher.post('http://api.example.com/user/5', {}, {})
|
19
9
|
end
|
20
10
|
|
21
|
-
|
22
|
-
|
23
|
-
stub_request(:post, "http://api.example.com/user/5").to_return(:body => {:base => { :a => :b } }.to_json, :status => "201")
|
24
|
-
@response = ApiClient::Dispatcher.post('http://api.example.com/user/5', {}, {})
|
25
|
-
end
|
26
|
-
|
27
|
-
it "should return the response code and the body parsed" do
|
28
|
-
ApiClient::Parser.response(@response, @remote_object).should == { "a" => "b" }
|
29
|
-
end
|
11
|
+
it "should return the response code and the body parsed" do
|
12
|
+
ApiClient::Parser.response(@response).should == { "base" => { "a" => "b" } }
|
30
13
|
end
|
31
14
|
end
|
32
15
|
|
@@ -37,7 +20,7 @@ describe ApiClient::Parser do
|
|
37
20
|
end
|
38
21
|
|
39
22
|
it "should return the response code and an empty hash" do
|
40
|
-
ApiClient::Parser.response(@response
|
23
|
+
ApiClient::Parser.response(@response).should == {}
|
41
24
|
end
|
42
25
|
end
|
43
26
|
|
@@ -49,7 +32,7 @@ describe ApiClient::Parser do
|
|
49
32
|
end
|
50
33
|
|
51
34
|
it "should return a Unauthorized exception" do
|
52
|
-
lambda { ApiClient::Parser.response(@response
|
35
|
+
lambda { ApiClient::Parser.response(@response) }.should raise_error(ApiClient::Exceptions::Unauthorized)
|
53
36
|
end
|
54
37
|
end
|
55
38
|
|
@@ -60,7 +43,7 @@ describe ApiClient::Parser do
|
|
60
43
|
end
|
61
44
|
|
62
45
|
it "should return a Forbidden exception" do
|
63
|
-
lambda { ApiClient::Parser.response(@response
|
46
|
+
lambda { ApiClient::Parser.response(@response) }.should raise_error(ApiClient::Exceptions::Forbidden)
|
64
47
|
end
|
65
48
|
end
|
66
49
|
|
@@ -71,7 +54,7 @@ describe ApiClient::Parser do
|
|
71
54
|
end
|
72
55
|
|
73
56
|
it "should return a NotFound exception" do
|
74
|
-
lambda { ApiClient::Parser.response(@response
|
57
|
+
lambda { ApiClient::Parser.response(@response) }.should raise_error(ApiClient::Exceptions::NotFound)
|
75
58
|
end
|
76
59
|
end
|
77
60
|
|
@@ -82,7 +65,7 @@ describe ApiClient::Parser do
|
|
82
65
|
end
|
83
66
|
|
84
67
|
it "should return a InternalServerError exception" do
|
85
|
-
lambda { ApiClient::Parser.response(@response
|
68
|
+
lambda { ApiClient::Parser.response(@response) }.should raise_error(ApiClient::Exceptions::InternalServerError)
|
86
69
|
end
|
87
70
|
end
|
88
71
|
|
@@ -93,7 +76,7 @@ describe ApiClient::Parser do
|
|
93
76
|
end
|
94
77
|
|
95
78
|
it "should return a BadGateway exception" do
|
96
|
-
lambda { ApiClient::Parser.response(@response
|
79
|
+
lambda { ApiClient::Parser.response(@response) }.should raise_error(ApiClient::Exceptions::BadGateway)
|
97
80
|
end
|
98
81
|
end
|
99
82
|
|
@@ -104,9 +87,9 @@ describe ApiClient::Parser do
|
|
104
87
|
end
|
105
88
|
|
106
89
|
it "should return a ServiceUnavailable exception" do
|
107
|
-
lambda { ApiClient::Parser.response(@response
|
90
|
+
lambda { ApiClient::Parser.response(@response) }.should raise_error(ApiClient::Exceptions::ServiceUnavailable)
|
108
91
|
end
|
109
92
|
end
|
110
93
|
end
|
111
94
|
end
|
112
|
-
end
|
95
|
+
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: api-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.7.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-09-
|
12
|
+
date: 2012-09-17 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
@@ -165,7 +165,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
165
165
|
version: '0'
|
166
166
|
segments:
|
167
167
|
- 0
|
168
|
-
hash:
|
168
|
+
hash: 3232996777461905993
|
169
169
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
170
170
|
none: false
|
171
171
|
requirements:
|
@@ -174,7 +174,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
174
174
|
version: '0'
|
175
175
|
segments:
|
176
176
|
- 0
|
177
|
-
hash:
|
177
|
+
hash: 3232996777461905993
|
178
178
|
requirements: []
|
179
179
|
rubyforge_project:
|
180
180
|
rubygems_version: 1.8.24
|