api-client 1.4.1 → 1.5.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.
@@ -1,5 +1,13 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## v1.4.1
4
+
5
+ * ActiveModel compatibility for errors added. make all error keys symbolic.
6
+
7
+ ## v1.4.0
8
+
9
+ * functionality to validate on client side using ApiClient::Base added
10
+
3
11
  ## v1.3.0
4
12
 
5
13
  * functionality to read args with a root node added.
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # ApiClient [![Build Status](https://secure.travis-ci.org/plribeiro3000/api-client.png)](http://travis-ci.org/plribeiro3000/api-client)
2
2
 
3
- Client to make Api calls inside Rails easily. The master only supports ruby-1.9.3.
3
+ Client to make Api calls easily. The master only supports ruby-1.9.3.
4
4
  For older versions, check branch retro-compatibility.
5
5
 
6
6
  ## Installation
@@ -17,7 +17,7 @@ Or install it yourself as:
17
17
 
18
18
  $ gem install api-client
19
19
 
20
- ## Usage
20
+ ## Basic Usage
21
21
 
22
22
  Add this to your ApplicationController:
23
23
 
@@ -39,6 +39,15 @@ Then, on your action, just put into it:
39
39
 
40
40
  @user = User.get("http://api.example.com/user/3")
41
41
 
42
+ ## Advanced Usage
43
+
44
+ ApiClient can read api responses with root nodes based on the name of the virtual class.
45
+ In Some cases, that is not the required behavior. To Redefine it, use remote_object method:
46
+
47
+ class Admin < ApiClient::Base
48
+ self.remote_object = "user"
49
+ end
50
+
42
51
  ## TODO
43
52
  * Add Support to Typhoeus and Faraday
44
53
  * Proper Treatment for validation errors
@@ -31,13 +31,16 @@ class ApiClient::Base
31
31
  false
32
32
  end
33
33
 
34
- # Return the an array of errors if existent, otherwise instantiate a new ApiClient::Errors object with self.
34
+ # Return the hash of errors if existent, otherwise instantiate a new ApiClient::Errors object with self.
35
35
  #
36
36
  # @return [ApiClient::Errors] the validation errors.
37
37
  def errors
38
38
  @errors ||= ApiClient::Errors.new(self)
39
39
  end
40
40
 
41
+ # Set the hash of errors, making keys symbolic.
42
+ #
43
+ # @param [Hash] errors of the object..
41
44
  def errors=(errors = {})
42
45
  @errors = Hash[errors.map{|(key,value)| [key.to_sym,value]}]
43
46
  end
@@ -134,6 +137,7 @@ class ApiClient::Base
134
137
  raise ApiClient::Exceptions::ConnectionRefused
135
138
  end
136
139
  raise_exception(code)
140
+ return object.map { |a| new(a) } if object.instance_of?(Array)
137
141
  new(object)
138
142
  end
139
143
 
@@ -6,12 +6,26 @@ module ApiClient::Parser
6
6
  # @return [Array] the code and the body parsed.
7
7
  def _response(response)
8
8
  begin
9
- body = JSON.parse(response.body)
10
- root_node = name.split('::').last.downcase
11
- object = body.key?(root_node) ? body[root_node] : body
9
+ object = JSON.parse(response.body)
10
+ object = object[remote_object] if object.key?(remote_object)
11
+ object = object[remote_object.pluralize] if object.key?(remote_object.pluralize)
12
12
  rescue JSON::ParserError
13
13
  object = nil
14
14
  end
15
15
  return response.code, object
16
16
  end
17
+
18
+ # Return the Remote Object Name.
19
+ #
20
+ # @return [String] a string with the remote object class name.
21
+ def remote_object
22
+ @remote_object.blank? ? self.to_s.split('::').last.downcase : @remote_object
23
+ end
24
+
25
+ # Set a custom remote object name instead of the virtual class name.
26
+ #
27
+ # @param [String] remote_object name.
28
+ def remote_object=(remote_object)
29
+ @remote_object = remote_object
30
+ end
17
31
  end
@@ -1,5 +1,5 @@
1
1
  # High Level Namespace of the library ApiClient.
2
2
  module ApiClient
3
3
  # Version of the library.
4
- VERSION = "1.4.1"
4
+ VERSION = "1.5.0"
5
5
  end
@@ -75,13 +75,59 @@ describe ApiClient::Base do
75
75
  end
76
76
 
77
77
  context "when response code is 2xx" do
78
- before :each do
79
- FakeWeb.register_uri(:delete, "http://api.example.com/user/5", :status => "201", :body => '{"a": "a", "b": "b"}')
80
- User.stub(:new).and_return(user)
78
+ context "without any specifications" do
79
+ before :each do
80
+ FakeWeb.register_uri(:delete, "http://api.example.com/user/5", :status => "201", :body => '{"a": "a", "b": "b"}')
81
+ User.stub(:new).and_return(user)
82
+ end
83
+
84
+ it "should return a object initialized with the response" do
85
+ User.delete('http://api.example.com/user/5').should == user
86
+ end
87
+ end
88
+
89
+ context "with a specified port" do
90
+ before :each do
91
+ FakeWeb.register_uri(:delete, "http://api.example.com:3001/user/5", :status => "201", :body => '{"a": "a", "b": "b"}')
92
+ User.stub(:new).and_return(user)
93
+ end
94
+
95
+ it "should return a object initialized with the response" do
96
+ User.delete('http://api.example.com:3001/user/5', {}).should == user
97
+ end
98
+ end
99
+
100
+ context "with a specified remote object name" do
101
+ before :each do
102
+ FakeWeb.register_uri(:delete, "http://api.example.com/user/5", :status => "201", :body => '{"user": {"a": "a", "b": "b"} }')
103
+ Admin.stub(:new).and_return(user)
104
+ end
105
+
106
+ it "should return a object initialized with the response" do
107
+ Admin.delete('http://api.example.com/user/5', {}).should == user
108
+ end
109
+ end
110
+
111
+ context "with a collection" do
112
+ before :each do
113
+ FakeWeb.register_uri(:delete, "http://api.example.com/user/5", :status => "201", :body => '{"users": [ {"a": "a", "b": "b"}, {"a": "a", "b": "b"} ] }')
114
+ User.stub(:new).and_return(user)
115
+ end
116
+
117
+ it "should return a collection of objects initialized with the response" do
118
+ User.delete('http://api.example.com/user/5', {}).should == [ user, user ]
119
+ end
81
120
  end
82
121
 
83
- it "should return a object intialized with the response" do
84
- User.delete('http://api.example.com/user/5').should == user
122
+ context "with a collection and a specified remote object name" do
123
+ before :each do
124
+ FakeWeb.register_uri(:delete, "http://api.example.com/user/5", :status => "201", :body => '{"users": [ {"a": "a", "b": "b"}, {"a": "a", "b": "b"} ] }')
125
+ Admin.stub(:new).and_return(user)
126
+ end
127
+
128
+ it "should return a collection of objects initialized with the response" do
129
+ Admin.delete('http://api.example.com/user/5', {}).should == [ user, user ]
130
+ end
85
131
  end
86
132
  end
87
133
  end
@@ -75,13 +75,59 @@ describe ApiClient::Base do
75
75
  end
76
76
 
77
77
  context "when response code is 2xx" do
78
- before :each do
79
- FakeWeb.register_uri(:get, "http://api.example.com/user/5", :status => "201", :body => '{"a": "a", "b": "b"}')
80
- User.stub(:new).and_return(user)
78
+ context "without any specifications" do
79
+ before :each do
80
+ FakeWeb.register_uri(:get, "http://api.example.com/user/5", :status => "201", :body => '{"a": "a", "b": "b"}')
81
+ User.stub(:new).and_return(user)
82
+ end
83
+
84
+ it "should return a object initialized with the response" do
85
+ User.get('http://api.example.com/user/5').should == user
86
+ end
87
+ end
88
+
89
+ context "with a specified port" do
90
+ before :each do
91
+ FakeWeb.register_uri(:get, "http://api.example.com:3001/user/5", :status => "201", :body => '{"a": "a", "b": "b"}')
92
+ User.stub(:new).and_return(user)
93
+ end
94
+
95
+ it "should return a object initialized with the response" do
96
+ User.get('http://api.example.com:3001/user/5', {}).should == user
97
+ end
98
+ end
99
+
100
+ context "with a specified remote object name" do
101
+ before :each do
102
+ FakeWeb.register_uri(:get, "http://api.example.com/user/5", :status => "201", :body => '{"user": {"a": "a", "b": "b"} }')
103
+ Admin.stub(:new).and_return(user)
104
+ end
105
+
106
+ it "should return a object initialized with the response" do
107
+ Admin.get('http://api.example.com/user/5', {}).should == user
108
+ end
109
+ end
110
+
111
+ context "with a collection" do
112
+ before :each do
113
+ FakeWeb.register_uri(:get, "http://api.example.com/user/5", :status => "201", :body => '{"users": [ {"a": "a", "b": "b"}, {"a": "a", "b": "b"} ] }')
114
+ User.stub(:new).and_return(user)
115
+ end
116
+
117
+ it "should return a collection of objects initialized with the response" do
118
+ User.get('http://api.example.com/user/5', {}).should == [ user, user ]
119
+ end
81
120
  end
82
121
 
83
- it "should return a object intialized with the response" do
84
- User.get('http://api.example.com/user/5').should == user
122
+ context "with a collection and a specified remote object name" do
123
+ before :each do
124
+ FakeWeb.register_uri(:get, "http://api.example.com/user/5", :status => "201", :body => '{"users": [ {"a": "a", "b": "b"}, {"a": "a", "b": "b"} ] }')
125
+ Admin.stub(:new).and_return(user)
126
+ end
127
+
128
+ it "should return a collection of objects initialized with the response" do
129
+ Admin.get('http://api.example.com/user/5', {}).should == [ user, user ]
130
+ end
85
131
  end
86
132
  end
87
133
  end
@@ -75,24 +75,59 @@ describe ApiClient::Base do
75
75
  end
76
76
 
77
77
  context "when response code is 2xx" do
78
- before :each do
79
- FakeWeb.register_uri(:patch, "http://api.example.com/user/5", :status => "201", :body => '{"a": "a", "b": "b"}')
80
- User.stub(:new).and_return(user)
78
+ context "without any specifications" do
79
+ before :each do
80
+ FakeWeb.register_uri(:patch, "http://api.example.com/user/5", :status => "201", :body => '{"a": "a", "b": "b"}')
81
+ User.stub(:new).and_return(user)
82
+ end
83
+
84
+ it "should return a object initialized with the response" do
85
+ User.patch('http://api.example.com/user/5', {}).should == user
86
+ end
81
87
  end
82
88
 
83
- it "should return a object initialized with the response" do
84
- User.patch('http://api.example.com/user/5', {}).should == user
89
+ context "with a specified port" do
90
+ before :each do
91
+ FakeWeb.register_uri(:patch, "http://api.example.com:3001/user/5", :status => "201", :body => '{"a": "a", "b": "b"}')
92
+ User.stub(:new).and_return(user)
93
+ end
94
+
95
+ it "should return a object initialized with the response" do
96
+ User.patch('http://api.example.com:3001/user/5', {}).should == user
97
+ end
85
98
  end
86
- end
87
99
 
88
- context "with a specified port" do
89
- before :each do
90
- FakeWeb.register_uri(:patch, "http://api.example.com:3001/user/5", :status => "201", :body => '{"a": "a", "b": "b"}')
91
- User.stub(:new).and_return(user)
100
+ context "with a specified remote object name" do
101
+ before :each do
102
+ FakeWeb.register_uri(:patch, "http://api.example.com/user/5", :status => "201", :body => '{"user": {"a": "a", "b": "b"} }')
103
+ Admin.stub(:new).and_return(user)
104
+ end
105
+
106
+ it "should return a object initialized with the response" do
107
+ Admin.patch('http://api.example.com/user/5', {}).should == user
108
+ end
92
109
  end
93
110
 
94
- it "should return a object initialized with the response" do
95
- User.patch('http://api.example.com:3001/user/5', {}).should == user
111
+ context "with a collection" do
112
+ before :each do
113
+ FakeWeb.register_uri(:patch, "http://api.example.com/user/5", :status => "201", :body => '{"users": [ {"a": "a", "b": "b"}, {"a": "a", "b": "b"} ] }')
114
+ User.stub(:new).and_return(user)
115
+ end
116
+
117
+ it "should return a collection of objects initialized with the response" do
118
+ User.patch('http://api.example.com/user/5', {}).should == [ user, user ]
119
+ end
120
+ end
121
+
122
+ context "with a collection and a specified remote object name" do
123
+ before :each do
124
+ FakeWeb.register_uri(:patch, "http://api.example.com/user/5", :status => "201", :body => '{"users": [ {"a": "a", "b": "b"}, {"a": "a", "b": "b"} ] }')
125
+ Admin.stub(:new).and_return(user)
126
+ end
127
+
128
+ it "should return a collection of objects initialized with the response" do
129
+ Admin.patch('http://api.example.com/user/5', {}).should == [ user, user ]
130
+ end
96
131
  end
97
132
  end
98
133
  end
@@ -75,24 +75,59 @@ describe ApiClient::Base do
75
75
  end
76
76
 
77
77
  context "when response code is 2xx" do
78
- before :each do
79
- FakeWeb.register_uri(:post, "http://api.example.com/user/5", :status => "201", :body => '{"a": "a", "b": "b"}')
80
- User.stub(:new).and_return(user)
78
+ context "without a specified port" do
79
+ before :each do
80
+ FakeWeb.register_uri(:post, "http://api.example.com/user/5", :status => "201", :body => '{"a": "a", "b": "b"}')
81
+ User.stub(:new).and_return(user)
82
+ end
83
+
84
+ it "should return a object initialized with the response" do
85
+ User.post('http://api.example.com/user/5', {}).should == user
86
+ end
81
87
  end
82
88
 
83
- it "should return a object initialized with the response" do
84
- User.post('http://api.example.com/user/5', {}).should == user
89
+ context "with a specified port" do
90
+ before :each do
91
+ FakeWeb.register_uri(:post, "http://api.example.com:3001/user/5", :status => "201", :body => '{"a": "a", "b": "b"}')
92
+ User.stub(:new).and_return(user)
93
+ end
94
+
95
+ it "should return a object initialized with the response" do
96
+ User.post('http://api.example.com:3001/user/5', {}).should == user
97
+ end
85
98
  end
86
- end
87
99
 
88
- context "with a specified port" do
89
- before :each do
90
- FakeWeb.register_uri(:post, "http://api.example.com:3001/user/5", :status => "201", :body => '{"a": "a", "b": "b"}')
91
- User.stub(:new).and_return(user)
100
+ context "with a specified remote object name" do
101
+ before :each do
102
+ FakeWeb.register_uri(:post, "http://api.example.com/user/5", :status => "201", :body => '{"user": {"a": "a", "b": "b"} }')
103
+ Admin.stub(:new).and_return(user)
104
+ end
105
+
106
+ it "should return a object initialized with the response" do
107
+ Admin.post('http://api.example.com/user/5', {}).should == user
108
+ end
92
109
  end
93
110
 
94
- it "should return a object initialized with the response" do
95
- User.post('http://api.example.com:3001/user/5', {}).should == user
111
+ context "with a collection" do
112
+ before :each do
113
+ FakeWeb.register_uri(:post, "http://api.example.com/user/5", :status => "201", :body => '{"users": [ {"a": "a", "b": "b"}, {"a": "a", "b": "b"} ] }')
114
+ User.stub(:new).and_return(user)
115
+ end
116
+
117
+ it "should return a collection of objects initialized with the response" do
118
+ User.post('http://api.example.com/user/5', {}).should == [ user, user ]
119
+ end
120
+ end
121
+
122
+ context "with a collection and a specified remote object name" do
123
+ before :each do
124
+ FakeWeb.register_uri(:post, "http://api.example.com/user/5", :status => "201", :body => '{"users": [ {"a": "a", "b": "b"}, {"a": "a", "b": "b"} ] }')
125
+ Admin.stub(:new).and_return(user)
126
+ end
127
+
128
+ it "should return a collection of objects initialized with the response" do
129
+ Admin.post('http://api.example.com/user/5', {}).should == [ user, user ]
130
+ end
96
131
  end
97
132
  end
98
133
  end
@@ -75,24 +75,59 @@ describe ApiClient::Base do
75
75
  end
76
76
 
77
77
  context "when response code is 2xx" do
78
- before :each do
79
- FakeWeb.register_uri(:put, "http://api.example.com/user/5", :status => "201", :body => '{"a": "a", "b": "b"}')
80
- User.stub(:new).and_return(user)
78
+ context "without a specified port" do
79
+ before :each do
80
+ FakeWeb.register_uri(:put, "http://api.example.com/user/5", :status => "201", :body => '{"a": "a", "b": "b"}')
81
+ User.stub(:new).and_return(user)
82
+ end
83
+
84
+ it "should return a object initialized with the response" do
85
+ User.put('http://api.example.com/user/5', {}).should == user
86
+ end
81
87
  end
82
88
 
83
- it "should return a object initialized with the response" do
84
- User.put('http://api.example.com/user/5', {}).should == user
89
+ context "with any specifications" do
90
+ before :each do
91
+ FakeWeb.register_uri(:put, "http://api.example.com:3001/user/5", :status => "201", :body => '{"a": "a", "b": "b"}')
92
+ User.stub(:new).and_return(user)
93
+ end
94
+
95
+ it "should return a object initialized with the response" do
96
+ User.put('http://api.example.com:3001/user/5', {}).should == user
97
+ end
85
98
  end
86
- end
87
99
 
88
- context "with a specified port" do
89
- before :each do
90
- FakeWeb.register_uri(:put, "http://api.example.com:3001/user/5", :status => "201", :body => '{"a": "a", "b": "b"}')
91
- User.stub(:new).and_return(user)
100
+ context "with a specified remote object name" do
101
+ before :each do
102
+ FakeWeb.register_uri(:put, "http://api.example.com/user/5", :status => "201", :body => '{"user": {"a": "a", "b": "b"} }')
103
+ Admin.stub(:new).and_return(user)
104
+ end
105
+
106
+ it "should return a object initialized with the response" do
107
+ Admin.put('http://api.example.com/user/5', {}).should == user
108
+ end
92
109
  end
93
110
 
94
- it "should return a object initialized with the response" do
95
- User.put('http://api.example.com:3001/user/5', {}).should == user
111
+ context "with a collection" do
112
+ before :each do
113
+ FakeWeb.register_uri(:put, "http://api.example.com/user/5", :status => "201", :body => '{"users": [ {"a": "a", "b": "b"}, {"a": "a", "b": "b"} ] }')
114
+ User.stub(:new).and_return(user)
115
+ end
116
+
117
+ it "should return a collection of objects initialized with the response" do
118
+ User.put('http://api.example.com/user/5', {}).should == [ user, user ]
119
+ end
120
+ end
121
+
122
+ context "with a collection and a specified remote object name" do
123
+ before :each do
124
+ FakeWeb.register_uri(:put, "http://api.example.com/user/5", :status => "201", :body => '{"users": [ {"a": "a", "b": "b"}, {"a": "a", "b": "b"} ] }')
125
+ Admin.stub(:new).and_return(user)
126
+ end
127
+
128
+ it "should return a collection of objects initialized with the response" do
129
+ Admin.put('http://api.example.com/user/5', {}).should == [ user, user ]
130
+ end
96
131
  end
97
132
  end
98
133
  end
@@ -43,4 +43,24 @@ describe ApiClient::Parser do
43
43
  end
44
44
  end
45
45
  end
46
+
47
+ describe "#remote_object" do
48
+ context "on a class without remote object specification" do
49
+ it "should return the class name" do
50
+ User.remote_object.should == "user"
51
+ end
52
+ end
53
+
54
+ context "on a class with remote object specification" do
55
+ it "should return the class name" do
56
+ Admin.remote_object.should == "user"
57
+ end
58
+ end
59
+ end
60
+
61
+ describe "#remote_object=" do
62
+ it "should set the remote object name" do
63
+ Admin.remote_object.should == "user"
64
+ end
65
+ end
46
66
  end
@@ -9,4 +9,10 @@ class User < ApiClient::Base
9
9
 
10
10
  validates_presence_of :a
11
11
  validates_inclusion_of :a, :in => %w(a A)
12
+ end
13
+
14
+ class Admin < ApiClient::Base
15
+ self.remote_object = "user"
16
+
17
+ attr_accessor :a, :b
12
18
  end
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.1
4
+ version: 1.5.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-07-12 00:00:00.000000000 Z
12
+ date: 2012-07-16 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake