api_client 0.5.24-java → 0.6.0-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +13 -0
  3. data/lib/api_client/base.rb +77 -0
  4. data/lib/api_client/connection/abstract.rb +81 -0
  5. data/lib/api_client/connection/basic.rb +131 -0
  6. data/lib/api_client/connection/json.rb +14 -0
  7. data/lib/api_client/connection/middlewares/request/json.rb +34 -0
  8. data/lib/api_client/connection/middlewares/request/logger.rb +64 -0
  9. data/lib/api_client/connection/middlewares/request/oauth.rb +22 -0
  10. data/lib/api_client/connection/oauth.rb +18 -0
  11. data/lib/api_client/errors.rb +32 -0
  12. data/lib/api_client/mixins/configuration.rb +24 -0
  13. data/lib/api_client/mixins/connection_hooks.rb +24 -0
  14. data/lib/api_client/mixins/delegation.rb +23 -0
  15. data/lib/api_client/mixins/inheritance.rb +19 -0
  16. data/lib/api_client/mixins/instantiation.rb +29 -0
  17. data/lib/api_client/mixins/scoping.rb +49 -0
  18. data/lib/api_client/resource/base.rb +67 -0
  19. data/lib/api_client/resource/name_resolver.rb +37 -0
  20. data/lib/api_client/resource/scope.rb +73 -0
  21. data/lib/api_client/scope.rb +125 -0
  22. data/lib/api_client/utils.rb +18 -0
  23. data/lib/api_client/version.rb +3 -0
  24. data/spec/api_client/base/connection_hook_spec.rb +18 -0
  25. data/spec/api_client/base/delegation_spec.rb +15 -0
  26. data/spec/api_client/base/inheritance_spec.rb +44 -0
  27. data/spec/api_client/base/instantiation_spec.rb +55 -0
  28. data/spec/api_client/base/marshalling_spec.rb +33 -0
  29. data/spec/api_client/base/parsing_spec.rb +38 -0
  30. data/spec/api_client/base/scoping_spec.rb +60 -0
  31. data/spec/api_client/base_spec.rb +107 -0
  32. data/spec/api_client/connection/abstract_spec.rb +21 -0
  33. data/spec/api_client/connection/basic_spec.rb +198 -0
  34. data/spec/api_client/connection/oauth_spec.rb +23 -0
  35. data/spec/api_client/connection/request/json_spec.rb +30 -0
  36. data/spec/api_client/connection/request/logger_spec.rb +18 -0
  37. data/spec/api_client/connection/request/oauth_spec.rb +26 -0
  38. data/spec/api_client/resource/base_spec.rb +97 -0
  39. data/spec/api_client/resource/name_spec.rb +19 -0
  40. data/spec/api_client/resource/scope_spec.rb +122 -0
  41. data/spec/api_client/scope_spec.rb +204 -0
  42. data/spec/api_client/utils_spec.rb +32 -0
  43. data/spec/support/matchers.rb +5 -0
  44. metadata +72 -11
@@ -0,0 +1,21 @@
1
+ require "spec_helper"
2
+
3
+ describe ApiClient::Connection::Abstract do
4
+
5
+ class ConnectionSubclass < ApiClient::Connection::Abstract
6
+ end
7
+
8
+ it "does not raise an error when instantiating a subclass" do
9
+ lambda {
10
+ ConnectionSubclass.new("http://google.com")
11
+ }.should_not raise_error()
12
+ end
13
+
14
+ it "raises an error when instantiating directly and not as a subclass" do
15
+ lambda {
16
+ ApiClient::Connection::Abstract.new("http://google.com")
17
+ }.should raise_error("Cannot instantiate abstract class")
18
+ end
19
+
20
+ end
21
+
@@ -0,0 +1,198 @@
1
+ require "spec_helper"
2
+
3
+ describe ApiClient::Connection::Basic do
4
+
5
+ it "has a nice inspect" do
6
+ instance = ApiClient::Connection::Basic.new("http://google.com")
7
+ instance.inspect.should == '#<ApiClient::Connection::Basic endpoint: "http://google.com">'
8
+ end
9
+
10
+ it "uses correct adapter" do
11
+ instance = ApiClient::Connection::Basic.new("http://google.com")
12
+ expect(instance.handler.builder.adapter.name).to eq("Faraday::Adapter::NetHttp")
13
+ end
14
+
15
+ it "adds basic middlewares to faraday" do
16
+ instance = ApiClient::Connection::Basic.new("http://google.com")
17
+ expect(instance.handler.builder.handlers.collect(&:name)).to include("Faraday::Request::UrlEncoded")
18
+ end
19
+
20
+ it "adds the logger middlewares to faraday if ApiClient.logger is available" do
21
+ logger = double
22
+ ApiClient.stub(:logger).and_return(logger)
23
+ instance = ApiClient::Connection::Basic.new("http://google.com")
24
+ expect(instance.handler.builder.handlers.collect(&:name)).to include("ApiClient::Connection::Middlewares::Request::Logger", "Faraday::Request::UrlEncoded")
25
+ end
26
+
27
+ it "creates a Faraday object on initialize" do
28
+ instance = ApiClient::Connection::Basic.new("http://google.com")
29
+ instance.handler.should be_an_instance_of(Faraday::Connection)
30
+ end
31
+
32
+ describe "requests" do
33
+
34
+ before do
35
+ @instance = ApiClient::Connection::Basic.new("http://google.com")
36
+ @headers = { "header" => "token" }
37
+ @params = { "param" => "1", "nested" => { "param" => "1" } }
38
+ @response = Faraday::Response.new(:status => 200)
39
+ @faraday_request_params = double
40
+ @faraday_request = double(:params => @faraday_request_params)
41
+ end
42
+
43
+ it "can perform GET requests" do
44
+ @instance.handler.
45
+ should_receive(:run_request).
46
+ with(:get, '/home', nil, @headers).
47
+ and_yield(@faraday_request).
48
+ and_return(@response)
49
+ @faraday_request_params.should_receive(:update).with(@params)
50
+ @instance.get "/home", @params, @headers
51
+ end
52
+
53
+ it "can perform POST requests" do
54
+ @instance.handler.
55
+ should_receive(:run_request).
56
+ with(:post, '/home', @params, @headers).
57
+ and_return(@response)
58
+ @instance.post "/home", @params, @headers
59
+ end
60
+
61
+ it "can perform PATCH requests" do
62
+ @instance.handler.
63
+ should_receive(:run_request).
64
+ with(:patch, '/home', @params, @headers).
65
+ and_return(@response)
66
+ @instance.patch "/home", @params, @headers
67
+ end
68
+
69
+ it "can perform PUT requests" do
70
+ @instance.handler.
71
+ should_receive(:run_request).
72
+ with(:put, '/home', @params, @headers).
73
+ and_return(@response)
74
+ @instance.put "/home", @params, @headers
75
+ end
76
+
77
+ it "can perform DELETE requests" do
78
+ @instance.handler.
79
+ should_receive(:run_request).
80
+ with(:delete, '/home', nil, @headers).
81
+ and_yield(@faraday_request).
82
+ and_return(@response)
83
+ @faraday_request_params.should_receive(:update).with(@params)
84
+ @instance.delete "/home", @params, @headers
85
+ end
86
+
87
+ end
88
+
89
+ describe "#handle_response" do
90
+ let(:request) { double }
91
+
92
+ before do
93
+ @instance = ApiClient::Connection::Basic.new("http://google.com")
94
+ @response = Faraday::Response.new(:status => 200)
95
+ end
96
+
97
+ it "raises an ApiClient::Errors::ConnectionFailed if there is no response" do
98
+ lambda {
99
+ @instance.send :handle_response, request, nil
100
+ }.should raise_error(ApiClient::Errors::ConnectionFailed, "ApiClient::Errors::ConnectionFailed")
101
+ end
102
+
103
+ it "raises an ApiClient::Errors::Unauthorized if status is 401" do
104
+ @response.env[:status] = 401
105
+ lambda {
106
+ @instance.send :handle_response, request, @response
107
+ }.should raise_error(ApiClient::Errors::Unauthorized, "Status code: 401")
108
+ end
109
+
110
+ it "raises an ApiClient::Errors::Forbidden if status is 403" do
111
+ @response.env[:status] = 403
112
+ lambda {
113
+ @instance.send :handle_response, request, @response
114
+ }.should raise_error(ApiClient::Errors::Forbidden, "Status code: 403")
115
+ end
116
+
117
+ it "raises an ApiClient::Errors::NotFound if status is 404" do
118
+ @response.env[:status] = 404
119
+ lambda {
120
+ @instance.send :handle_response, request, @response
121
+ }.should raise_error(ApiClient::Errors::NotFound, "Status code: 404")
122
+ end
123
+
124
+ it "raises an ApiClient::Errors::BadRequest if status is 400" do
125
+ @response.env[:status] = 400
126
+ lambda {
127
+ @instance.send :handle_response, request, @response
128
+ }.should raise_error(ApiClient::Errors::BadRequest, "Status code: 400")
129
+ end
130
+
131
+ it "raises an ApiClient::Errors::Unsupported if status is 406" do
132
+ @response.env[:status] = 406
133
+ lambda {
134
+ @instance.send :handle_response, request, @response
135
+ }.should raise_error(ApiClient::Errors::Unsupported, "Status code: 406")
136
+ end
137
+
138
+ it "raises an ApiClient::Errors::Conflict if status is 409" do
139
+ @response.env[:status] = 409
140
+ lambda {
141
+ @instance.send :handle_response, request, @response
142
+ }.should raise_error(ApiClient::Errors::Conflict, "Status code: 409")
143
+ end
144
+
145
+ it "raises an ApiClient::Errors::Gone if status is 410" do
146
+ @response.env[:status] = 410
147
+ lambda {
148
+ @instance.send :handle_response, request, @response
149
+ }.should raise_error(ApiClient::Errors::Gone, "Status code: 410")
150
+ end
151
+
152
+ it "raises an ApiClient::Errors::PreconditionFailed if status is 412" do
153
+ @response.env[:status] = 412
154
+ lambda {
155
+ @instance.send :handle_response, request, @response
156
+ }.should raise_error(ApiClient::Errors::PreconditionFailed, "Status code: 412")
157
+ end
158
+
159
+ it "raises an ApiClient::Errors::Unsupported if status is 422" do
160
+ @response.env[:status] = 422
161
+ lambda {
162
+ @instance.send :handle_response, request, @response
163
+ }.should raise_error(ApiClient::Errors::UnprocessableEntity, @response.body)
164
+ end
165
+
166
+ it "raises an ApiClient::Errors::Locked if status is 423" do
167
+ @response.env[:status] = 423
168
+ lambda {
169
+ @instance.send :handle_response, request, @response
170
+ }.should raise_error(ApiClient::Errors::Locked, @response.body)
171
+ end
172
+
173
+ it "raises an ApiClient::Errors::TooManyRequests if status is 429" do
174
+ @response.env[:status] = 429
175
+ lambda {
176
+ @instance.send :handle_response, request, @response
177
+ }.should raise_error(ApiClient::Errors::TooManyRequests, @response.body)
178
+ end
179
+
180
+ it "raises an ApiClient::Errors::Unsupported if status is 300..399" do
181
+ location = "https://google.com"
182
+ @response.env[:status] = 302
183
+ @response.env[:response_headers] = { 'Location' => location }
184
+ lambda {
185
+ @instance.send :handle_response, request, @response
186
+ }.should raise_error(ApiClient::Errors::Redirect, location)
187
+ end
188
+
189
+ it "raises an ApiClient::Errors::ServerError if status is 500..599" do
190
+ @response.env[:status] = 502
191
+ lambda {
192
+ @instance.send :handle_response, request, @response
193
+ }.should raise_error(ApiClient::Errors::ServerError, "Status code: 502")
194
+ end
195
+
196
+ end
197
+
198
+ end
@@ -0,0 +1,23 @@
1
+ require "spec_helper"
2
+
3
+ describe ApiClient::Connection::Oauth do
4
+
5
+ it "uses correct adapter" do
6
+ instance = ApiClient::Connection::Oauth.new("http://google.com")
7
+ expect(instance.handler.builder.adapter.name).to eq("Faraday::Adapter::NetHttp")
8
+ end
9
+
10
+ it "adds basic middlewares to faraday" do
11
+ instance = ApiClient::Connection::Oauth.new("http://google.com")
12
+ expect(instance.handler.builder.handlers.collect(&:name))
13
+ .to include("ApiClient::Connection::Middlewares::Request::OAuth", "Faraday::Request::UrlEncoded")
14
+ end
15
+
16
+ it "adds the logger middlewares to faraday if ApiClient.logger is available" do
17
+ logger = double
18
+ ApiClient.stub(:logger).and_return(logger)
19
+ instance = ApiClient::Connection::Oauth.new("http://google.com")
20
+ expect(instance.handler.builder.handlers.collect(&:name))
21
+ .to include("ApiClient::Connection::Middlewares::Request::Logger", "ApiClient::Connection::Middlewares::Request::OAuth", "Faraday::Request::UrlEncoded")
22
+ end
23
+ end
@@ -0,0 +1,30 @@
1
+ require "spec_helper"
2
+
3
+ describe ApiClient::Connection::Middlewares::Request::Json do
4
+ let(:app) { double }
5
+ let(:body) { {:some => :data} }
6
+ let(:env) do
7
+ {
8
+ :url => "http://api.twitter.com",
9
+ :request_headers => {},
10
+ :method => "post",
11
+ :body => body
12
+ }
13
+ end
14
+
15
+ subject { ApiClient::Connection::Middlewares::Request::Json.new(app) }
16
+
17
+ it "sets content type to json" do
18
+ app.should_receive(:call).
19
+ with(hash_including(:request_headers => {"Content-Type" => "application/json"}))
20
+
21
+ subject.call(env)
22
+ end
23
+
24
+ it "JSON encodes body" do
25
+ app.should_receive(:call).
26
+ with(hash_including(:body => MultiJson.dump(body)))
27
+
28
+ subject.call(env)
29
+ end
30
+ end
@@ -0,0 +1,18 @@
1
+ require "spec_helper"
2
+
3
+ describe ApiClient::Connection::Middlewares::Request::Logger do
4
+ it "adds a oauth header to the request" do
5
+ app = double
6
+ io = StringIO.new
7
+ logger = Logger.new(io)
8
+ instance = ApiClient::Connection::Middlewares::Request::Logger.new(app, logger)
9
+ env = {
10
+ :url => "http://api.twitter.com",
11
+ :request_headers => {},
12
+ :method => 'get'
13
+ }
14
+ app.should_receive(:call).with(env)
15
+ instance.call(env)
16
+ io.string.should match("GET http://api.twitter.com")
17
+ end
18
+ end
@@ -0,0 +1,26 @@
1
+ require "spec_helper"
2
+
3
+ describe ApiClient::Connection::Middlewares::Request::OAuth do
4
+
5
+ it "adds a oauth header to the request" do
6
+ app = double
7
+ options = {
8
+ :token => 'TOKEN',
9
+ :token_secret => 'SECRET',
10
+ :consumer_key => 'CONSUMER_KEY',
11
+ :consumer_secret => 'CONSUMER_SECRET'
12
+ }
13
+ instance = ApiClient::Connection::Middlewares::Request::OAuth.new(app, options)
14
+ env = {
15
+ :url => "http://api.twitter.com",
16
+ :request_headers => {}
17
+ }
18
+ app.should_receive(:call).with(env)
19
+
20
+ instance.call(env)
21
+ env[:request_headers]['Authorization'].should match("OAuth")
22
+ env[:request_headers]['User-Agent'].should match("ApiClient gem")
23
+
24
+ end
25
+
26
+ end
@@ -0,0 +1,97 @@
1
+ require "spec_helper"
2
+
3
+ describe ApiClient::Resource::Base do
4
+
5
+ describe '.scope' do
6
+
7
+ it "is an instance of ApiClient::Resource::Scope" do
8
+ ApiClient::Resource::Base.scope.should be_an_instance_of(ApiClient::Resource::Scope)
9
+ end
10
+
11
+ end
12
+
13
+
14
+ describe "persistence" do
15
+
16
+ before do
17
+ @instance = ApiClient::Resource::Base.new
18
+ @instance.id = 42
19
+ @instance.name = "Mike"
20
+ end
21
+
22
+ describe '#persisted?' do
23
+
24
+ it "returns true if id is present, false otherwise" do
25
+ @instance.id = 42
26
+ @instance.persisted?.should == true
27
+ @instance.id = nil
28
+ @instance.persisted?.should == false
29
+ end
30
+
31
+ end
32
+
33
+ describe '#save' do
34
+
35
+ it "creates a record if not persisted" do
36
+ @instance.id = nil
37
+ @instance.should_receive(:remote_create)
38
+ @instance.save
39
+ end
40
+
41
+ it "updates a record if not persisted" do
42
+ @instance.id = 42
43
+ @instance.should_receive(:remote_update)
44
+ @instance.save
45
+ end
46
+
47
+ end
48
+
49
+ describe "#destroy" do
50
+
51
+ it "delegates the destroy to the class" do
52
+ ApiClient::Resource::Base.should_receive(:destroy).with(42)
53
+ @instance.destroy
54
+ end
55
+
56
+ it "retains the original scope" do
57
+ @instance.original_scope = double
58
+ @instance.original_scope.should_receive(:destroy).with(42)
59
+ @instance.destroy
60
+ end
61
+
62
+ end
63
+
64
+ describe "#remote_update" do
65
+
66
+ it "delegates the update to the class" do
67
+ ApiClient::Resource::Base.should_receive(:update).with(42, "name" => "Mike")
68
+ @instance.remote_update
69
+ end
70
+
71
+ it "retains the original scope" do
72
+ ApiClient::Resource::Base.stub(:update)
73
+ @instance.original_scope = double
74
+ @instance.original_scope.should_receive(:update).with(42, "name" => "Mike")
75
+ @instance.remote_update
76
+ end
77
+
78
+ end
79
+
80
+ describe "#remote_create" do
81
+
82
+ it "delegates the create to the class" do
83
+ ApiClient::Resource::Base.should_receive(:create).with("name" => "Mike")
84
+ @instance.remote_create
85
+ end
86
+
87
+ it "retains the original scope" do
88
+ @instance.original_scope = double
89
+ @instance.original_scope.should_receive(:create).with("name" => "Mike")
90
+ @instance.remote_create
91
+ end
92
+
93
+ end
94
+
95
+ end
96
+
97
+ end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ describe ApiClient::Resource::NameResolver do
4
+ describe '.resolve' do
5
+ subject { described_class }
6
+
7
+ it 'changes My::Namespace::MyResouce to my_resource' do
8
+ subject.resolve('My::Namespace::MyResource').should == 'my_resource'
9
+ end
10
+
11
+ it 'changes Resource to resource' do
12
+ subject.resolve('Resource').should == 'resource'
13
+ end
14
+
15
+ it 'changes My::Resource to resoure' do
16
+ subject.resolve('My::Resource').should == 'resource'
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,122 @@
1
+ require "spec_helper"
2
+
3
+ describe ApiClient::Resource::Scope do
4
+
5
+ describe "restful requests" do
6
+
7
+ class Restful < ApiClient::Resource::Base
8
+ end
9
+
10
+ class Restful2 < ApiClient::Resource::Base
11
+ namespace false
12
+ end
13
+
14
+ class Restful3 < ApiClient::Resource::Base
15
+ prefix "v1"
16
+ end
17
+
18
+ before do
19
+ @instance = ApiClient::Resource::Scope.new(Restful)
20
+ end
21
+
22
+ it "performs a find to fetch one record" do
23
+ response = { "restful" => { "id" => 42 }}
24
+ @instance.should_receive(:get).with('/restfuls/1.json').and_return(response)
25
+ result = @instance.find(1)
26
+ result.should be_an_instance_of(Restful)
27
+ result.id.should == 42
28
+ end
29
+
30
+ it "performs a find to fetch one record in raw mode" do
31
+ response = { "restful" => { "id" => 42 }}
32
+ @instance.should_receive(:get).with('/restfuls/1.json').and_return(response)
33
+ result = @instance.raw.find(1)
34
+ result.should == response
35
+ end
36
+
37
+ it "performs a find to fetch one record with a prefix if provided" do
38
+ @instance = ApiClient::Resource::Scope.new(Restful3)
39
+ response = { "restful3" => { "id" => 42 }}
40
+ @instance.should_receive(:get).with('/v1/restful3s/1.json').and_return(response)
41
+ result = @instance.find(1)
42
+ result.should be_an_instance_of(Restful3)
43
+ result.id.should == 42
44
+ end
45
+
46
+ it "performs a find_all to fetch many records" do
47
+ response = [{ "restful" => { "id" => 42 } }, { "restful" => { "id" => 112 } }]
48
+ @instance.should_receive(:get).with('/restfuls.json', {}).and_return(response)
49
+ result = @instance.find_all
50
+
51
+ result.should be_an_instance_of(Array)
52
+ result.first.should be_an_instance_of(Restful)
53
+ result.first.id.should == 42
54
+ result.last.should be_an_instance_of(Restful)
55
+ result.last.id.should == 112
56
+ end
57
+
58
+ it "performs a find_all to fetch many records in raw mode" do
59
+ response = [{ "restful" => { "id" => 42 } }, { "restful" => { "id" => 112 } }]
60
+ @instance.should_receive(:get).with('/restfuls.json', {}).and_return(response)
61
+ result = @instance.raw.find_all
62
+ result.should == response
63
+ end
64
+
65
+ it "performs a create to create a new record" do
66
+ response = { "restful" => { "id" => 42, "name" => "Foo" }}
67
+ @instance.should_receive(:post).with('/restfuls.json', {"restful" => {:name => "Foo"} }).and_return(response)
68
+ result = @instance.create(:name => "Foo")
69
+ result.should be_an_instance_of(Restful)
70
+ result.id.should == 42
71
+ end
72
+
73
+ it "performs a create to create a new record in raw mode" do
74
+ response = { "restful" => { "id" => 42, "name" => "Foo" }}
75
+ @instance.should_receive(:post).with('/restfuls.json', {"restful" => {:name => "Foo"} }).and_return(response)
76
+ result = @instance.raw.create(:name => "Foo")
77
+ result.should == response
78
+ end
79
+
80
+ it "performs a create to create a new record skipping the namespace if it is not present" do
81
+ @instance = ApiClient::Resource::Scope.new(Restful2)
82
+ response = { "id" => 42, "name" => "Foo" }
83
+ @instance.should_receive(:post).with('/restful2s.json', {:name => "Foo"} ).and_return(response)
84
+ result = @instance.create(:name => "Foo")
85
+ result.should be_an_instance_of(Restful2)
86
+ result.id.should == 42
87
+ end
88
+
89
+ it "performs a update to update an existing record" do
90
+ response = { "restful" => { "id" => 42, "name" => "Foo" }}
91
+ @instance.should_receive(:put).with('/restfuls/42.json', {"restful" => {:name => "Foo"} }).and_return(response)
92
+ result = @instance.update(42, :name => "Foo")
93
+ result.should be_an_instance_of(Restful)
94
+ result.id.should == 42
95
+ end
96
+
97
+ it "performs a update to update an existing record in raw mode" do
98
+ response = { "restful" => { "id" => 42, "name" => "Foo" }}
99
+ @instance.should_receive(:put).with('/restfuls/42.json', {"restful" => {:name => "Foo"} }).and_return(response)
100
+ result = @instance.raw.update(42, :name => "Foo")
101
+ result.should == response
102
+ end
103
+
104
+ it "performs a update to update an existing record skipping the namespace if it is not present" do
105
+ @instance = ApiClient::Resource::Scope.new(Restful2)
106
+ response = { "id" => 42, "name" => "Foo" }
107
+ @instance.should_receive(:put).with('/restful2s/42.json', {:name => "Foo"} ).and_return(response)
108
+ result = @instance.update(42, :name => "Foo")
109
+ result.should be_an_instance_of(Restful2)
110
+ result.id.should == 42
111
+ end
112
+
113
+ it "performs a destroy to remove a record" do
114
+ response = { "restful" => { "id" => 42, "name" => "Foo" }}
115
+ @instance.should_receive(:delete).with('/restfuls/42.json').and_return(response)
116
+ result = @instance.destroy(42)
117
+ result.should == true
118
+ end
119
+
120
+ end
121
+
122
+ end