api_client 0.5.24-java → 0.5.25-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 +4 -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 +129 -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 +31 -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 +191 -0
  34. data/spec/api_client/connection/oauth_spec.rb +27 -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 +62 -1
@@ -0,0 +1,27 @@
1
+ require "spec_helper"
2
+
3
+ describe ApiClient::Connection::Oauth do
4
+
5
+ it "adds basic middlewares to faraday" do
6
+ instance = ApiClient::Connection::Oauth.new("http://google.com")
7
+ instance.handler.builder.handlers.collect(&:name).should == [
8
+ "ApiClient::Connection::Middlewares::Request::OAuth",
9
+ "Faraday::Request::UrlEncoded",
10
+ "Faraday::Adapter::NetHttp"
11
+ ]
12
+ end
13
+
14
+ it "adds the logger middlewares to faraday if ApiClient.logger is available" do
15
+ logger = double
16
+ ApiClient.stub(:logger).and_return(logger)
17
+ instance = ApiClient::Connection::Oauth.new("http://google.com")
18
+ instance.handler.builder.handlers.collect(&:name).should == [
19
+ "ApiClient::Connection::Middlewares::Request::Logger",
20
+ "ApiClient::Connection::Middlewares::Request::OAuth",
21
+ "Faraday::Request::UrlEncoded",
22
+ "Faraday::Adapter::NetHttp"
23
+ ]
24
+
25
+ end
26
+
27
+ 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
@@ -0,0 +1,204 @@
1
+ require "spec_helper"
2
+
3
+ describe ApiClient::Scope do
4
+
5
+ describe 'default_scopes' do
6
+
7
+ it "runs the default scopes defined in the scopeable" do
8
+ class DefaultScopeTest < ApiClient::Base
9
+ always do
10
+ params :foo => 1
11
+ end
12
+ end
13
+ instance = ApiClient::Scope.new(DefaultScopeTest)
14
+ instance.params.should == { :foo => 1 }
15
+ end
16
+ end
17
+
18
+ describe "#params" do
19
+
20
+ it "reads/writes the params and chains nicely" do
21
+ instance = ApiClient::Scope.new(ApiClient::Base)
22
+ instance.params(:foo => 1).params(:moo => 10).should == instance
23
+ instance.params.should == { :foo => 1, :moo => 10 }
24
+ end
25
+
26
+ end
27
+
28
+ describe "#headers" do
29
+
30
+ it "reads/writes the headers and chains nicely" do
31
+ instance = ApiClient::Scope.new(ApiClient::Base)
32
+ instance.headers(:foo => 1).headers(:moo => 10).should == instance
33
+ instance.headers.should == { :foo => 1, :moo => 10 }
34
+ end
35
+
36
+ end
37
+
38
+ describe "#options" do
39
+
40
+ it "reads/writes the headers and chains nicely" do
41
+ instance = ApiClient::Scope.new(ApiClient::Base)
42
+ instance.options(:foo => 1).options(:moo => 10).should == instance
43
+ instance.options.should == { :foo => 1, :moo => 10 }
44
+ end
45
+
46
+ end
47
+
48
+ describe "#raw_body" do
49
+
50
+ it "reads/writes non-hash body" do
51
+ instance = ApiClient::Scope.new(ApiClient::Base)
52
+ instance.raw_body('raw body string').should == instance
53
+ instance.raw_body.should == 'raw body string'
54
+ end
55
+
56
+ it "overwrites previous raw_body" do
57
+ instance = ApiClient::Scope.new(ApiClient::Base)
58
+ instance.raw_body('previous').raw_body('current')
59
+ instance.raw_body.should == 'current'
60
+ end
61
+
62
+ it "does request with raw body only if set, skips other params" do
63
+ connection = double
64
+ instance = ApiClient::Scope.new(ApiClient::Base)
65
+ instance.stub(:connection).and_return(connection)
66
+ response = Faraday::Response.new(:body => '{"a": "1"}')
67
+ connection.should_receive(:get).with(@path, 'raw body string', {}).and_return(response)
68
+
69
+ result = instance.params({:skipped => 'params'}).raw_body('raw body string').request(:get, @path)
70
+ result.should == {"a"=> "1"}
71
+ end
72
+
73
+ end
74
+
75
+ describe "connection" do
76
+
77
+ it "retuns the connection based on the adapter" do
78
+ instance = ApiClient::Scope.new(ApiClient::Base)
79
+ instance.connection.should be_an_instance_of ApiClient::Connection::Basic
80
+ end
81
+
82
+ it "raises an error if adapter was not found" do
83
+ instance = ApiClient::Scope.new(ApiClient::Base)
84
+ lambda {
85
+ instance.adapter("foo").connection
86
+ }.should raise_error
87
+ end
88
+
89
+ it "executes connection hooks" do
90
+ AConnectionHook = double
91
+ class ScopeConnectionHooksTest < ApiClient::Base
92
+ end
93
+ ScopeConnectionHooksTest.connection_hooks = [AConnectionHook]
94
+ instance = ApiClient::Scope.new(ScopeConnectionHooksTest)
95
+ AConnectionHook.should_receive(:call)
96
+ instance.connection
97
+ end
98
+
99
+ end
100
+
101
+ describe "requests" do
102
+
103
+ before do
104
+ @path = "somepath"
105
+ @params = { :foo => 1 }
106
+ @headers = { 'token' => 'A' }
107
+ end
108
+
109
+ def test_request(method)
110
+ connection = double
111
+ instance = ApiClient::Scope.new(ApiClient::Base)
112
+ instance.stub(:connection).and_return(connection)
113
+ response = Faraday::Response.new(:body => '{"a": "1"}')
114
+ connection.should_receive(method).with(@path, @params, @headers).and_return(response)
115
+ instance.params(@params).headers(@headers).send(method, @path)
116
+ end
117
+
118
+ it "can make any request" do
119
+ connection = double
120
+ instance = ApiClient::Scope.new(ApiClient::Base)
121
+ instance.stub(:connection).and_return(connection)
122
+ response = Faraday::Response.new(:body => '{"a": "1"}')
123
+ connection.should_receive(:get).with(@path, @params, @headers).and_return(response)
124
+ result = instance.params(@params).headers(@headers).request(:get, @path)
125
+ result.should == {"a"=> "1"}
126
+ end
127
+
128
+ it "can make any request and get a raw response" do
129
+ connection = double
130
+ instance = ApiClient::Scope.new(ApiClient::Base)
131
+ instance.stub(:connection).and_return(connection)
132
+ response = Faraday::Response.new(:body => '{"a": "1"}')
133
+ connection.should_receive(:get).twice.with(@path, @params, @headers).and_return(response)
134
+ result = instance.params(@params).headers(@headers).request(:get, @path, :raw => true)
135
+ result.should == response
136
+ result = instance.raw.params(@params).headers(@headers).request(:get, @path)
137
+ result.should == response
138
+ end
139
+
140
+ it "makes a GET request" do
141
+ result = test_request :get
142
+ result.should == {"a"=> "1"}
143
+ end
144
+
145
+ it "makes a POST request" do
146
+ result = test_request :post
147
+ result.should == {"a"=> "1"}
148
+ end
149
+
150
+ it "makes a PATCH request" do
151
+ result = test_request :patch
152
+ result.should == {"a"=> "1"}
153
+ end
154
+
155
+ it "makes a PUT request" do
156
+ result = test_request :put
157
+ result.should == {"a"=> "1"}
158
+ end
159
+
160
+ it "makes a PUT request" do
161
+ result = test_request :delete
162
+ result.should == {"a"=> "1"}
163
+ end
164
+
165
+ describe "fetch" do
166
+
167
+ it "performs a get and builds an object" do
168
+ connection = double
169
+ instance = ApiClient::Scope.new(ApiClient::Base)
170
+ instance.stub(:connection).and_return(connection)
171
+ response = Faraday::Response.new(:body => '{"id": 42}')
172
+ connection.should_receive(:get).with(@path, @params, @headers).and_return(response)
173
+ result = instance.params(@params).headers(@headers).fetch(@path)
174
+ result.should be_an_instance_of(ApiClient::Base)
175
+ result.id.should == 42
176
+ end
177
+
178
+ end
179
+
180
+ end
181
+
182
+ describe "dynamic delegation of scopeable singleton methods" do
183
+
184
+ it "dynamically delegates and properly scopes" do
185
+ class DynamicDelegationTest < ApiClient::Base
186
+ def self.some_method
187
+ self.scope.params
188
+ end
189
+ end
190
+ scope = ApiClient::Scope.new(DynamicDelegationTest)
191
+ scope.params(:param => "aaa").some_method.should == { :param => "aaa" }
192
+ end
193
+
194
+ it "raises an error if scopeable does not implement the method" do
195
+ scope = ApiClient::Scope.new(ApiClient::Base)
196
+ lambda {
197
+ scope.some_method_the_class_does_not_have
198
+ }.should raise_error(NoMethodError)
199
+ end
200
+
201
+ end
202
+
203
+
204
+ end