api_client 0.5.24-java → 0.5.25-java

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.
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