bootic_client 0.0.7 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8095f21114667841cc61f8048100b8f31e56f34e
4
- data.tar.gz: 1022b40385355b90b2a478af677dd7221d5bc68b
3
+ metadata.gz: 1ca933989403d66243755d735272c645458c5575
4
+ data.tar.gz: bdbdb38d2b417c05634953ffb48395d3f2971301
5
5
  SHA512:
6
- metadata.gz: ff530bf2fc8d5c4215ddf7838685fb7550e6e38b2085c109d8d5878ddae3ef263cb667803f751dfba15cfe0e8be127cbcf9654e9735091b87ba0164334039e00
7
- data.tar.gz: aada7437aa9a191accd6cd72e96fd21ff22fb85cd53ebe024929523d9ace1c95fe02fd24ff953a51b6b5bbdfb8ff547b46878a1193bbc8b30d63a1657d68a6c4
6
+ metadata.gz: c76703781e56dc5ee87eb065355fb8de38daf775f5fc38989e626985abe0a12e3800d94334482405081281ffbdbae295c8e9a66915e6e1f6b2c3f1f0b977b0f4
7
+ data.tar.gz: b5eac3f968ba339d877a798929c123c25beea50eae2f83e04078935ccbce24b97e57833ad398593d97d1dfbe057619bcc4286a0f5199cf2918968a0fd80c24f8
data/README.md CHANGED
@@ -115,6 +115,20 @@ client = BooticClient.client(:client_credentials, scope: 'admin', access_token:
115
115
  end
116
116
  ```
117
117
 
118
+ ### 3. Basic Auth
119
+
120
+ This strategy uses a `username` and `password` against APIs supporting HTTP's Basic Authentication scheme.
121
+
122
+ The official Bootic API only supports OAuth2 tokens, but this allows the client to be used against internal APIs or stub APIs on development.
123
+
124
+ ```ruby
125
+ client = BooticClient.client(:basic_auth, username: 'foo', password: 'bar')
126
+
127
+ root = client.root # etc
128
+ ```
129
+
130
+ NOTE: `username` and `password` have nothing to do with your Bootic administrative credentials, and will be up to API maintainers to define.
131
+
118
132
  ## Non GET links
119
133
 
120
134
  Most resource links lead to `GET` resources, but some will expect `POST`, `PUT`, `DELETE` or others.
@@ -186,6 +200,23 @@ BooticClient.configure do |c|
186
200
  end
187
201
  ```
188
202
 
203
+ ## Pre-loaded or custom root resources
204
+
205
+ This client is designed to always navigate APIs starting from the root endpoint (the Hypermedia approach), but it's also possible to skip the root and start from a locally defined resource definition.
206
+
207
+ ```ruby
208
+ messaging_api = client.from_hash(
209
+ "_links" => {
210
+ "send_message" => {"href" => 'https://some.api.com/messages', "method" => 'post'},
211
+ "delete_message" => {"href" => 'https://some.api.com/messages/:id', "method" => 'delete', "templated" => true}
212
+ }
213
+ )
214
+
215
+ new_message = messaging_api.send_message(title: 'This is a new message')
216
+
217
+ messaging_api.delete_message(id: new_message.id)
218
+ ```
219
+
189
220
  ## Contributing
190
221
 
191
222
  1. Fork it
@@ -15,7 +15,6 @@ module BooticClient
15
15
 
16
16
  def initialize(options = {}, &block)
17
17
  @options = {
18
- access_token: nil,
19
18
  logging: false
20
19
  }.merge(options.dup)
21
20
 
@@ -24,32 +23,38 @@ module BooticClient
24
23
  conn &block if block_given?
25
24
  end
26
25
 
27
- def get(href, query = {})
26
+ def get(href, query = {}, headers = {})
28
27
  validated_request!(:get, href) do |req|
28
+ req.headers.update headers
29
29
  req.params.update(query)
30
30
  end
31
31
  end
32
32
 
33
- def post(href, payload = {})
33
+ def post(href, payload = {}, headers = {})
34
34
  validated_request!(:post, href) do |req|
35
+ req.headers.update headers
35
36
  req.body = JSON.dump(payload)
36
37
  end
37
38
  end
38
39
 
39
- def put(href, payload = {})
40
+ def put(href, payload = {}, headers = {})
40
41
  validated_request!(:put, href) do |req|
42
+ req.headers.update headers
41
43
  req.body = JSON.dump(payload)
42
44
  end
43
45
  end
44
46
 
45
- def patch(href, payload = {})
47
+ def patch(href, payload = {}, headers = {})
46
48
  validated_request!(:patch, href) do |req|
49
+ req.headers.update headers
47
50
  req.body = JSON.dump(payload)
48
51
  end
49
52
  end
50
53
 
51
- def delete(href, query = {})
52
- validated_request!(:delete, href)
54
+ def delete(href, headers = {})
55
+ validated_request!(:delete, href) do |req|
56
+ req.headers.update headers
57
+ end
53
58
  end
54
59
 
55
60
  protected
@@ -69,7 +74,6 @@ module BooticClient
69
74
 
70
75
  def request_headers
71
76
  {
72
- 'Authorization' => "Bearer #{options[:access_token]}",
73
77
  'User-Agent' => USER_AGENT,
74
78
  'Accept' => JSON_MIME,
75
79
  'Content-Type' => JSON_MIME
@@ -77,7 +81,6 @@ module BooticClient
77
81
  end
78
82
 
79
83
  def validated_request!(verb, href, &block)
80
- validate_request!
81
84
  resp = conn.send(verb) do |req|
82
85
  req.url href
83
86
  req.headers.update request_headers
@@ -88,10 +91,6 @@ module BooticClient
88
91
  resp
89
92
  end
90
93
 
91
- def validate_request!
92
- raise NoAccessTokenError, "Missing access token" unless options[:access_token]
93
- end
94
-
95
94
  def raise_if_invalid!(resp)
96
95
  raise ServerError, "Server Error" if resp.status > 499
97
96
  raise NotFoundError, "Not Found" if resp.status == 404
@@ -41,7 +41,8 @@ module BooticClient
41
41
  end
42
42
 
43
43
  def [](key)
44
- properties[key.to_sym] || entities[key.to_sym]
44
+ key = key.to_sym
45
+ has_property?(key) ? properties[key] : entities[key]
45
46
  end
46
47
 
47
48
  def has?(prop_name)
@@ -2,8 +2,7 @@ module BooticClient
2
2
  class TransportError < StandardError; end
3
3
  class ServerError < TransportError; end
4
4
  class NotFoundError < ServerError; end
5
- class TokenError < ServerError; end
6
- class UnauthorizedError < TokenError; end
7
- class AccessForbiddenError < TokenError; end
8
- class NoAccessTokenError < TokenError; end
9
- end
5
+ class AuthorizationError < ServerError; end
6
+ class UnauthorizedError < AuthorizationError; end
7
+ class AccessForbiddenError < AuthorizationError; end
8
+ end
@@ -45,7 +45,11 @@ module BooticClient
45
45
 
46
46
  def run(opts = {})
47
47
  if templated?
48
- client.request_and_wrap transport_method.to_sym, uri.expand(opts), wrapper_class, opts
48
+ uri_vars = uri.variables
49
+ payload = opts.each_with_object({}) do |(k,v),memo|
50
+ memo[k] = v unless uri_vars.include?(k.to_s)
51
+ end
52
+ client.request_and_wrap transport_method.to_sym, uri.expand(opts), wrapper_class, payload
49
53
  else
50
54
  client.request_and_wrap transport_method.to_sym, href, wrapper_class, opts
51
55
  end
@@ -1,13 +1,13 @@
1
- require 'bootic_client/strategies/strategy'
1
+ require 'bootic_client/strategies/oauth2_strategy'
2
2
 
3
3
  module BooticClient
4
4
  module Strategies
5
5
 
6
- class Authorized < Strategy
6
+ class Authorized < Oauth2Strategy
7
7
  protected
8
8
 
9
- def validate!(options)
10
- raise "options MUST include access_token" unless options[:access_token]
9
+ def validate!
10
+ raise ArgumentError, "options MUST include access_token" unless options[:access_token]
11
11
  end
12
12
 
13
13
  def get_token
@@ -0,0 +1,27 @@
1
+ require 'bootic_client/strategies/strategy'
2
+
3
+ module BooticClient
4
+ module Strategies
5
+ class BasicAuth < Strategy
6
+
7
+ def inspect
8
+ %(#<#{self.class.name} root: #{config.api_root} username: #{options[:username]}>)
9
+ end
10
+
11
+ protected
12
+
13
+ def validate!
14
+ raise ArgumentError, "options MUST include username" unless options[:username]
15
+ raise ArgumentError, "options MUST include password" unless options[:password]
16
+ end
17
+
18
+ def client
19
+ @client ||= Client.new(options) do |c|
20
+ c.request :basic_auth, options[:username], options[:password]
21
+ end
22
+ end
23
+ end
24
+ end
25
+
26
+ strategies[:basic_auth] = Strategies::BasicAuth
27
+ end
@@ -1,10 +1,11 @@
1
- require 'bootic_client/strategies/strategy'
1
+ require 'bootic_client/strategies/oauth2_strategy'
2
2
 
3
3
  module BooticClient
4
4
  module Strategies
5
5
 
6
- class ClientCredentials < Strategy
6
+ class ClientCredentials < Oauth2Strategy
7
7
  protected
8
+
8
9
  def get_token
9
10
  opts = {}
10
11
  opts['scope'] = options.delete(:scope) if options[:scope]
@@ -16,4 +17,4 @@ module BooticClient
16
17
  end
17
18
 
18
19
  strategies[:client_credentials] = Strategies::ClientCredentials
19
- end
20
+ end
@@ -0,0 +1,61 @@
1
+ require 'oauth2'
2
+ require 'bootic_client/strategies/strategy'
3
+
4
+ module BooticClient
5
+ module Strategies
6
+
7
+ class Oauth2Strategy < Strategy
8
+
9
+ def inspect
10
+ %(#<#{self.class.name} cid: #{config.client_id} root: #{config.api_root} auth: #{config.auth_host}>)
11
+ end
12
+
13
+ protected
14
+
15
+ def validate!
16
+ raise ArgumentError, "MUST include client_id" unless config.client_id
17
+ raise ArgumentError, "MUST include client_secret" unless config.client_secret
18
+ raise ArgumentError, "MUST include api_root" unless config.api_root
19
+ end
20
+
21
+ def pre_flight
22
+ update_token! unless options[:access_token]
23
+ end
24
+
25
+ def request_headers
26
+ {
27
+ 'Authorization' => "Bearer #{options[:access_token]}"
28
+ }
29
+ end
30
+
31
+ def retryable(&block)
32
+ begin
33
+ yield
34
+ rescue AuthorizationError => e
35
+ update_token!
36
+ yield
37
+ end
38
+ end
39
+
40
+ def update_token!
41
+ new_token = get_token
42
+ options[:access_token] = new_token
43
+ on_new_token.call new_token
44
+ end
45
+
46
+ def get_token
47
+ raise "Implement this in subclasses"
48
+ end
49
+
50
+ def auth
51
+ @auth ||= OAuth2::Client.new(
52
+ config.client_id,
53
+ config.client_secret,
54
+ site: config.auth_host
55
+ )
56
+ end
57
+
58
+ end
59
+
60
+ end
61
+ end
@@ -1,5 +1,3 @@
1
- require 'oauth2'
2
-
3
1
  module BooticClient
4
2
  module Strategies
5
3
  class Strategy
@@ -8,11 +6,7 @@ module BooticClient
8
6
 
9
7
  def initialize(config, client_opts = {}, &on_new_token)
10
8
  @config, @options, @on_new_token = config, client_opts, (on_new_token || Proc.new{})
11
- raise "MUST include client_id" unless config.client_id
12
- raise "MUST include client_secret" unless config.client_secret
13
- raise "MUST include api_root" unless config.api_root
14
- validate! @options
15
- reset!
9
+ validate!
16
10
  end
17
11
 
18
12
  def root
@@ -24,43 +18,56 @@ module BooticClient
24
18
  end
25
19
 
26
20
  def request_and_wrap(request_method, href, wrapper_class, payload = {})
27
- begin
28
- wrapper_class.new client.send(request_method, href, payload).body, self
29
- rescue TokenError => e
30
- new_token = get_token
31
- options[:access_token] = new_token
32
- reset!
33
- on_new_token.call new_token
34
- wrapper_class.new client.send(request_method, href, payload).body, self
21
+ pre_flight
22
+ retryable do
23
+ wrapper_class.new client.send(request_method, href, payload, request_headers).body, self
35
24
  end
36
25
  end
37
26
 
38
27
  def inspect
39
- %(#<#{self.class.name} cid: #{config.client_id} root: #{config.api_root} auth: #{config.auth_host}>)
28
+ %(#<#{self.class.name} root: #{config.api_root}>)
40
29
  end
41
30
 
42
31
  protected
43
32
 
44
- attr_reader :config, :on_new_token, :client
33
+ attr_reader :config, :on_new_token
34
+
35
+ def validate!
36
+ # Overwrite in sub classes
37
+ # to raise ArgumentErrors on
38
+ # missing config attributes of options values.
39
+ end
45
40
 
46
- def validate!(options)
47
-
41
+ def pre_flight
42
+ # Runs before every request
43
+ # Overwrite in sub classes to run checks
44
+ # (ie authorisation status, missing options, expired token refresh)
48
45
  end
49
46
 
50
- def get_token
51
- raise "Implement this in subclasses"
47
+ # Noop.
48
+ # Overwrite in sub classes to implement retryable requests.
49
+ # Example:
50
+ #
51
+ # def retryable(&block)
52
+ # begin
53
+ # yield # issue request
54
+ # rescue SomeException => e
55
+ # fix_cause_of_exception
56
+ # yield # try again
57
+ # end
58
+ # end
59
+ #
60
+ def retryable(&block)
61
+ yield
52
62
  end
53
63
 
54
- def auth
55
- @auth ||= OAuth2::Client.new(
56
- config.client_id,
57
- config.client_secret,
58
- site: config.auth_host
59
- )
64
+ # Noop. Merge these headers into every request.
65
+ def request_headers
66
+ {}
60
67
  end
61
68
 
62
- def reset!
63
- @client = Client.new(options)
69
+ def client
70
+ @client ||= Client.new(options)
64
71
  end
65
72
  end
66
73
  end
@@ -1,3 +1,3 @@
1
1
  module BooticClient
2
- VERSION = "0.0.7"
2
+ VERSION = "0.0.8"
3
3
  end
@@ -55,7 +55,7 @@ describe 'BooticClient::Strategies::Authorized' do
55
55
  it 'raises error' do
56
56
  expect{
57
57
  BooticClient.client(:authorized)
58
- }.to raise_error
58
+ }.to raise_error(ArgumentError)
59
59
  end
60
60
  end
61
61
 
@@ -63,7 +63,7 @@ describe 'BooticClient::Strategies::Authorized' do
63
63
  it 'raises error' do
64
64
  expect{
65
65
  BooticClient.client(:authorized)
66
- }.to raise_error
66
+ }.to raise_error(ArgumentError)
67
67
  end
68
68
  end
69
69
 
@@ -0,0 +1,71 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'BooticClient::Strategies::BasicAuth' do
4
+ require 'webmock/rspec'
5
+
6
+ let(:root_data) {
7
+ {
8
+ '_links' => {
9
+ 'a_product' => {'href' => 'https://api.bootic.net/v1/products/1'}
10
+ },
11
+ 'message' => "Hello!"
12
+ }
13
+ }
14
+
15
+ let(:product_data) {
16
+ {'title' => 'iPhone 6 Plus'}
17
+ }
18
+
19
+ let(:client) { BooticClient.client(:basic_auth, username: 'foo', password: 'bar') }
20
+
21
+ describe '#inspect' do
22
+ it 'is informative' do
23
+ expect(client.inspect).to eql %(#<BooticClient::Strategies::BasicAuth root: https://api.bootic.net/v1 username: foo>)
24
+ end
25
+ end
26
+
27
+ context 'with missing credentials' do
28
+ it 'raises error' do
29
+ expect{
30
+ BooticClient.client(:basic_auth)
31
+ }.to raise_error(ArgumentError)
32
+ end
33
+ end
34
+
35
+ context 'with invalid BasicAuth credentials' do
36
+ let!(:root_request) do
37
+ stub_request(:get, 'https://foo:bar@api.bootic.net/v1')
38
+ .to_return(status: 401, body: JSON.dump(root_data))
39
+ end
40
+
41
+ it 'raises an Unauthorized error' do
42
+ expect{ client.root }.to raise_error(BooticClient::UnauthorizedError)
43
+ expect(root_request).to have_been_requested
44
+ end
45
+ end
46
+
47
+ context 'with valid BasicAuth credentials' do
48
+ let!(:root_request) do
49
+ stub_request(:get, 'https://foo:bar@api.bootic.net/v1')
50
+ .to_return(status: 200, body: JSON.dump(root_data))
51
+ end
52
+
53
+ let!(:product_request) do
54
+ stub_request(:get, 'https://foo:bar@api.bootic.net/v1/products/1')
55
+ .to_return(status: 200, body: JSON.dump(product_data))
56
+ end
57
+
58
+ let!(:root) { client.root }
59
+
60
+ it 'includes Basic Auth credentials in request' do
61
+ expect(root_request).to have_been_requested
62
+ expect(root.message).to eql('Hello!')
63
+ end
64
+
65
+ it 'follows links as normal, including Basic Auth in every request' do
66
+ product = root.a_product
67
+ expect(product_request).to have_been_requested
68
+ expect(product.title).to eql 'iPhone 6 Plus'
69
+ end
70
+ end
71
+ end
@@ -18,7 +18,7 @@ describe 'BooticClient::Strategies::ClientCredentials' do
18
18
  BooticClient.client_id = nil
19
19
  expect{
20
20
  BooticClient.client(:client_credentials, scope: 'admin')
21
- }.to raise_error
21
+ }.to raise_error(ArgumentError)
22
22
  end
23
23
  end
24
24
 
@@ -33,7 +33,7 @@ describe 'BooticClient::Strategies::ClientCredentials' do
33
33
  def stub_api_root(access_token, status, body)
34
34
  stub_request(:get, "https://api.bootic.net/v1").
35
35
  with(headers: {'Accept'=>'application/json', 'Authorization'=>"Bearer #{access_token}"}).
36
- to_return(status: status, :body => JSON.dump(body))
36
+ to_return(status: status, body: JSON.dump(body))
37
37
  end
38
38
 
39
39
  before do
data/spec/client_spec.rb CHANGED
@@ -6,9 +6,9 @@ describe BooticClient::Client do
6
6
 
7
7
  describe 'valid response' do
8
8
  let(:root_url) { 'https://api.bootic.net/v1' }
9
- let(:client) { BooticClient::Client.new(access_token: 'xxx') }
9
+ let(:client) { BooticClient::Client.new }
10
10
  let(:request_headers) {
11
- {'Accept' => 'application/json', 'Authorization' => "Bearer xxx"}
11
+ {'Authorization' => "Bearer xxx"}
12
12
  }
13
13
  let(:response_headers) {
14
14
  {
@@ -35,7 +35,7 @@ describe BooticClient::Client do
35
35
  .to_return(status: 200, body: JSON.dump(root_data), headers: response_headers)
36
36
  end
37
37
 
38
- let!(:response) { client.get(root_url) }
38
+ let!(:response) { client.get(root_url, {}, request_headers) }
39
39
 
40
40
  it 'returns parsed Faraday response' do
41
41
  expect(response).to be_kind_of(Faraday::Response)
@@ -53,7 +53,7 @@ describe BooticClient::Client do
53
53
  end
54
54
 
55
55
  it 'returns cached response' do
56
- r = client.get(root_url)
56
+ r = client.get(root_url, {}, request_headers)
57
57
  expect(@cached_request).to have_been_requested
58
58
 
59
59
  expect(r.status).to eql(200)
@@ -71,7 +71,7 @@ describe BooticClient::Client do
71
71
  end
72
72
 
73
73
  it 'returns cached response' do
74
- r = client.get(root_url)
74
+ r = client.get(root_url, {}, request_headers)
75
75
  expect(@cached_request).to have_been_requested
76
76
 
77
77
  expect(r.status).to eql(200)
@@ -83,14 +83,6 @@ describe BooticClient::Client do
83
83
  end
84
84
 
85
85
  context 'errors' do
86
- describe 'no access token' do
87
- it 'raises error' do
88
- expect{
89
- BooticClient::Client.new.get(root_url)
90
- }.to raise_error(BooticClient::NoAccessTokenError)
91
- end
92
- end
93
-
94
86
  describe '500 Server error' do
95
87
  before do
96
88
  stub_request(:get, root_url)
@@ -156,7 +148,7 @@ describe BooticClient::Client do
156
148
  end
157
149
 
158
150
  it 'GETs response' do
159
- expect(client.get(root_url, foo: 'bar').body['message']).to eql('Hello!')
151
+ expect(client.get(root_url, {foo: 'bar'}, request_headers).body['message']).to eql('Hello!')
160
152
  end
161
153
  end
162
154
 
@@ -168,7 +160,7 @@ describe BooticClient::Client do
168
160
  end
169
161
 
170
162
  it 'POSTs request and parses response' do
171
- expect(client.post(root_url, foo: 'bar').body['message']).to eql('Hello!')
163
+ expect(client.post(root_url, {foo: 'bar'}, request_headers).body['message']).to eql('Hello!')
172
164
  end
173
165
  end
174
166
 
@@ -181,7 +173,7 @@ describe BooticClient::Client do
181
173
  end
182
174
 
183
175
  it "#{verb.to_s.upcase}s request and parses response" do
184
- expect(client.send(verb, root_url, foo: 'bar').body['message']).to eql('Hello!')
176
+ expect(client.send(verb, root_url, {foo: 'bar'}, request_headers).body['message']).to eql('Hello!')
185
177
  end
186
178
  end
187
179
  end
@@ -194,7 +186,7 @@ describe BooticClient::Client do
194
186
  end
195
187
 
196
188
  it 'DELETEs request and parses response' do
197
- expect(client.send(:delete, root_url).status).to eql(200)
189
+ expect(client.send(:delete, root_url, request_headers).status).to eql(200)
198
190
  expect(@delete_requst).to have_been_requested
199
191
  end
200
192
  end
data/spec/entity_spec.rb CHANGED
@@ -29,6 +29,7 @@ describe BooticClient::Entity do
29
29
  {
30
30
  'title' => 'iPhone 4',
31
31
  'price' => 12345,
32
+ 'published' => false,
32
33
  '_links' => {
33
34
  'self' => {href: '/products/iphone4'},
34
35
  'btc:delete_product' => {'href' => '/products/12345'}
@@ -43,6 +44,7 @@ describe BooticClient::Entity do
43
44
  {
44
45
  'title' => 'iPhone 5',
45
46
  'price' => 12342,
47
+ 'published' => true,
46
48
  '_links' => {
47
49
  'self' => {href: '/products/iphone5'}
48
50
  },
@@ -52,7 +54,7 @@ describe BooticClient::Entity do
52
54
  }
53
55
  }
54
56
  }
55
-
57
+
56
58
  ] # / items
57
59
  }
58
60
  }
@@ -118,6 +120,11 @@ describe BooticClient::Entity do
118
120
  expect(shop.name).to eql('Acme')
119
121
  end
120
122
  end
123
+
124
+ it 'includes FALSE values' do
125
+ expect(entity.items.first.published).to be false
126
+ expect(entity.items.last.published).to be true
127
+ end
121
128
  end #/ embedded entities
122
129
 
123
130
  describe 'link relations' do
@@ -161,7 +168,7 @@ describe BooticClient::Entity do
161
168
  end
162
169
 
163
170
  it 'takes optional URI parameters' do
164
- expect(client).to receive(:request_and_wrap).with(:get, '/search?q=foo', BooticClient::Entity, {q: 'foo'}).and_return next_page
171
+ expect(client).to receive(:request_and_wrap).with(:get, '/search?q=foo', BooticClient::Entity, {}).and_return next_page
165
172
  entity.search(q: 'foo').tap do |next_entity|
166
173
  expect(next_entity).to be_kind_of(BooticClient::Entity)
167
174
  expect(next_entity.page).to eql(2)
@@ -48,8 +48,8 @@ describe BooticClient::Relation do
48
48
  end
49
49
 
50
50
  it 'interpolates tokens' do
51
- expect(client).to receive(:request_and_wrap).with(:get, '/foos/2?q=test&page=2', BooticClient::Entity, {id:2,q:'test',page:2}).and_return entity
52
- expect(relation.run(id: 2, q: 'test', page: 2)).to eql(entity)
51
+ expect(client).to receive(:request_and_wrap).with(:get, '/foos/2?q=test&page=2', BooticClient::Entity, {other: 'other'}).and_return entity
52
+ expect(relation.run(id: 2, q: 'test', page: 2, other: 'other')).to eql(entity)
53
53
  end
54
54
  end
55
55
  end
@@ -62,9 +62,9 @@ describe BooticClient::Relation do
62
62
  client.stub(:request_and_wrap).with(:post, '/foo/bars', BooticClient::Entity, {}).and_return entity
63
63
  expect(relation.run).to eql(entity)
64
64
  end
65
-
65
+
66
66
  it 'interpolates templated URLs' do
67
- client.stub(:request_and_wrap).with(:post, '/foo/123', BooticClient::Entity, {foo: 'bar', bars: 123}).and_return entity
67
+ client.stub(:request_and_wrap).with(:post, '/foo/123', BooticClient::Entity, {foo: 'bar'}).and_return entity
68
68
  expect(relation_templated.run(bars: 123, foo: 'bar')).to eql(entity)
69
69
  end
70
70
  end
data/spec/spec_helper.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
2
  require 'bootic_client'
3
+ require 'byebug'
3
4
 
4
5
  RSpec.configure do |config|
5
6
  config.expect_with :rspec do |c|
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bootic_client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7
4
+ version: 0.0.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ismael Celis
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-03-07 00:00:00.000000000 Z
11
+ date: 2015-04-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -186,10 +186,13 @@ files:
186
186
  - lib/bootic_client/relation.rb
187
187
  - lib/bootic_client/stores/memcache.rb
188
188
  - lib/bootic_client/strategies/authorized.rb
189
+ - lib/bootic_client/strategies/basic_auth.rb
189
190
  - lib/bootic_client/strategies/client_credentials.rb
191
+ - lib/bootic_client/strategies/oauth2_strategy.rb
190
192
  - lib/bootic_client/strategies/strategy.rb
191
193
  - lib/bootic_client/version.rb
192
194
  - spec/authorized_strategy_spec.rb
195
+ - spec/basic_auth_strategy_spec.rb
193
196
  - spec/bootic_client_spec.rb
194
197
  - spec/client_credentials_strategy_spec.rb
195
198
  - spec/client_spec.rb
@@ -223,6 +226,7 @@ specification_version: 4
223
226
  summary: Official Ruby client for the Bootic API
224
227
  test_files:
225
228
  - spec/authorized_strategy_spec.rb
229
+ - spec/basic_auth_strategy_spec.rb
226
230
  - spec/bootic_client_spec.rb
227
231
  - spec/client_credentials_strategy_spec.rb
228
232
  - spec/client_spec.rb