bootic_client 0.0.7 → 0.0.8

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