bootic_client 0.0.18 → 0.0.19

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: 7a89d8b5c05c6db2600def4db1c010412968182c
4
- data.tar.gz: 407389c386a7f6323a4651b7200ce00881c9b0e9
3
+ metadata.gz: dcfbbb311b78031493af896f6db383dfebdffd82
4
+ data.tar.gz: ddbeb3d2dd2ff06defbaa67acdfbd32006fa074e
5
5
  SHA512:
6
- metadata.gz: 703206264feeb2ce9e7baa20da05704655736e6429c9df239dadb6c7f7b6b59af21a154be20665d31760a372e829606665f68852c4a025a55bd20ce418fdbc63
7
- data.tar.gz: 7001187975d691991a6ef3df1e8641776fdd42bc0462c3ad6f1580a6805a455cb2cccc2e64f82000f46ac5b05978c5015b65e797644047df06c9a18e4ca9718a
6
+ metadata.gz: b510fb186560ceeda306b87a72e22cdfbed0df944fc04c9950bf07ac9c6ec9bbb169914487d3ada5405fa57817c76b1c656e0fd209da015354057187042a7c97
7
+ data.tar.gz: a026d7e471ec31d53fd302f43afc8b6a80a24eaa2f827958c02ad6d6c543b4d9f4860c8158fad123a624dbb6ed67fcf482a91a6058fa7a041a44610e2311f414
@@ -1,5 +1,12 @@
1
1
  # Change Log
2
2
 
3
+ ## [v0.0.18](https://github.com/bootic/bootic_client.rb/tree/v0.0.18) (2017-04-03)
4
+ [Full Changelog](https://github.com/bootic/bootic_client.rb/compare/v0.0.17...v0.0.18)
5
+
6
+ **Merged pull requests:**
7
+
8
+ - Bearer token strategy [\#10](https://github.com/bootic/bootic_client.rb/pull/10) ([ismasan](https://github.com/ismasan))
9
+
3
10
  ## [v0.0.17](https://github.com/bootic/bootic_client.rb/tree/v0.0.17) (2017-04-02)
4
11
  [Full Changelog](https://github.com/bootic/bootic_client.rb/compare/v0.0.16...v0.0.17)
5
12
 
data/README.md CHANGED
@@ -39,7 +39,7 @@ end
39
39
  ### Using with an existing access token
40
40
 
41
41
  ```ruby
42
- bootic = BooticClient.client(:authorized, access_token: 'beidjbewjdiedue...', logging: true)
42
+ bootic = BooticClient.client(:authorized, access_token: 'beidjbewjdiedue...')
43
43
 
44
44
  root = bootic.root
45
45
 
@@ -134,6 +134,12 @@ NOTE: `username` and `password` have nothing to do with your Bootic administrati
134
134
  This strategy adds an access token as a header in the format `Authorization: Bearer <your-token-here>`.
135
135
  It will not try to refresh an expired token from an Oauth2 server, so there's no need to configure Oauth2 credentials.
136
136
 
137
+ ```ruby
138
+ client = BooticClient.client(:bearer, access_token: 'foobar')
139
+
140
+ root = client.root # etc
141
+ ```
142
+
137
143
  Use this with APIs that don't expire tokens, or for testing.
138
144
 
139
145
  ## Non GET links
@@ -5,4 +5,6 @@ module BooticClient
5
5
  class AuthorizationError < ServerError; end
6
6
  class UnauthorizedError < AuthorizationError; end
7
7
  class AccessForbiddenError < AuthorizationError; end
8
+ class ClientError < TransportError; end
9
+ class InvalidURLError < ClientError; end
8
10
  end
@@ -1,4 +1,4 @@
1
- require 'uri_template'
1
+ require "bootic_client/whiny_uri"
2
2
  require "bootic_client/entity"
3
3
 
4
4
  module BooticClient
@@ -6,6 +6,8 @@ module BooticClient
6
6
  class Relation
7
7
 
8
8
  GET = 'get'.freeze
9
+ HEAD = 'head'.freeze
10
+ OPTIONS = 'options'.freeze
9
11
 
10
12
  def initialize(attrs, client, wrapper_class = Entity)
11
13
  @attrs, @client, @wrapper_class = attrs, client, wrapper_class
@@ -48,7 +50,7 @@ module BooticClient
48
50
  end
49
51
 
50
52
  def transport_method
51
- @transport_method ||= attrs['method'] || GET
53
+ @transport_method ||= attrs.key?('method') ? attrs['method'].to_s.downcase : GET
52
54
  end
53
55
 
54
56
  def run(opts = {})
@@ -57,6 +59,8 @@ module BooticClient
57
59
  payload = opts.each_with_object({}) do |(k,v),memo|
58
60
  memo[k] = v unless uri_vars.include?(k.to_s)
59
61
  end
62
+ # remove payload vars from URI opts if destructive action
63
+ opts = opts.reject{|k, v| !uri_vars.include?(k.to_s) } if destructive?
60
64
  client.request_and_wrap transport_method.to_sym, uri.expand(opts), wrapper_class, payload
61
65
  else
62
66
  client.request_and_wrap transport_method.to_sym, href, wrapper_class, opts
@@ -64,15 +68,18 @@ module BooticClient
64
68
  end
65
69
 
66
70
  def self.expand(href, opts = {})
67
- URITemplate.new(href).expand(opts)
71
+ WhinyURI.new(href).expand(opts)
68
72
  end
69
73
 
70
74
  protected
71
75
  attr_reader :wrapper_class, :client, :attrs
72
76
 
73
77
  def uri
74
- @uri ||= URITemplate.new(href)
78
+ @uri ||= WhinyURI.new(href)
75
79
  end
76
- end
77
80
 
81
+ def destructive?
82
+ ![GET, OPTIONS, HEAD].include? transport_method
83
+ end
84
+ end
78
85
  end
@@ -1,3 +1,3 @@
1
1
  module BooticClient
2
- VERSION = "0.0.18"
2
+ VERSION = "0.0.19"
3
3
  end
@@ -0,0 +1,62 @@
1
+ require 'uri_template'
2
+
3
+ module BooticClient
4
+ class WhinyURI
5
+ attr_reader :variables
6
+
7
+ def initialize(href)
8
+ @href = href
9
+ @uri = URITemplate.new(href)
10
+ @variables = @uri.variables
11
+ end
12
+
13
+ def expand(attrs = {})
14
+ missing = missing_path_variables(attrs)
15
+ if missing.any?
16
+ raise InvalidURLError, missing_err(missing)
17
+ end
18
+
19
+ undeclared = undeclared_params(attrs)
20
+ if undeclared.any?
21
+ raise InvalidURLError, undeclared_err(undeclared)
22
+ end
23
+
24
+ uri.expand attrs
25
+ end
26
+
27
+ private
28
+ attr_reader :uri, :href
29
+
30
+ def path_variables
31
+ @path_variables ||= (
32
+ variables.find_all{ |v|
33
+ Regexp.new("(\/\{#{v}\})|(\{\/#{v}\})") =~ href
34
+ }
35
+ )
36
+ end
37
+
38
+ def missing_path_variables(attrs)
39
+ path_variables - attrs.keys.map(&:to_s)
40
+ end
41
+
42
+ def undeclared_params(attrs)
43
+ attrs.keys.map(&:to_s) - variables
44
+ end
45
+
46
+ def undeclared_err(undeclared)
47
+ msg = ["undeclared URI variables: #{format_vars(undeclared)}"]
48
+ query_vars = variables - path_variables
49
+ msg << "Allowed query variables are #{format_vars(query_vars)}" if query_vars.any?
50
+ msg.join('. ')
51
+ end
52
+
53
+ def missing_err(missing)
54
+ "missing required path variables: #{format_vars(missing)}"
55
+ end
56
+
57
+ def format_vars(vars)
58
+ vars.map{|v| "`#{v}`"}.join(', ')
59
+ end
60
+ end
61
+ end
62
+
@@ -54,9 +54,15 @@ describe BooticClient::Relation do
54
54
  expect(relation.templated?).to eql(true)
55
55
  end
56
56
 
57
+ it 'complains if missing path variables' do
58
+ expect{
59
+ relation.run
60
+ }.to raise_error BooticClient::InvalidURLError
61
+ end
62
+
57
63
  it 'works with defaults' do
58
- expect(client).to receive(:request_and_wrap).with(:get, '/foos/', BooticClient::Entity, {}).and_return entity
59
- expect(relation.run).to eql(entity)
64
+ expect(client).to receive(:request_and_wrap).with(:get, '/foos/123', BooticClient::Entity, {}).and_return entity
65
+ expect(relation.run(id: 123)).to eql(entity)
60
66
  end
61
67
 
62
68
  it 'has parameter list' do
@@ -64,8 +70,14 @@ describe BooticClient::Relation do
64
70
  end
65
71
 
66
72
  it 'interpolates tokens' do
67
- expect(client).to receive(:request_and_wrap).with(:get, '/foos/2?q=test&page=2', BooticClient::Entity, {other: 'other'}).and_return entity
68
- expect(relation.run(id: 2, q: 'test', page: 2, other: 'other')).to eql(entity)
73
+ expect(client).to receive(:request_and_wrap).with(:get, '/foos/2?q=test&page=2', BooticClient::Entity, {}).and_return entity
74
+ expect(relation.run(id: 2, q: 'test', page: 2)).to eql(entity)
75
+ end
76
+
77
+ it 'complains if passing undeclared query variables' do
78
+ expect{
79
+ relation.run(id: 2, q: 'test', page: 2, other: 'foo')
80
+ }.to raise_error BooticClient::InvalidURLError
69
81
  end
70
82
  end
71
83
  end
@@ -79,7 +91,7 @@ describe BooticClient::Relation do
79
91
  expect(relation.run).to eql(entity)
80
92
  end
81
93
 
82
- it 'interpolates templated URLs' do
94
+ it 'interpolates templated URLs and sends remaining as BODY' do
83
95
  allow(client).to receive(:request_and_wrap).with(:post, '/foo/123', BooticClient::Entity, {foo: 'bar'}).and_return entity
84
96
  expect(relation_templated.run(bars: 123, foo: 'bar')).to eql(entity)
85
97
  end
@@ -0,0 +1,52 @@
1
+ require 'spec_helper'
2
+ require "bootic_client/whiny_uri"
3
+
4
+ describe BooticClient::WhinyURI do
5
+ describe '#expand' do
6
+ let(:uri) {
7
+ described_class.new('http://www.host.com/shops/{id}/{?foo}')
8
+ }
9
+
10
+ it 'complains if missing a path segment' do
11
+ expect{
12
+ uri.expand(foo: 1)
13
+ }.to raise_error BooticClient::InvalidURLError
14
+ end
15
+
16
+ it 'understand different path segment syntax' do
17
+ uri = described_class.new('http://www.host.com/shops{/id}/{?foo}')
18
+ expect{
19
+ uri.expand(foo: 1)
20
+ }.to raise_error BooticClient::InvalidURLError
21
+ end
22
+
23
+ it 'expands if all path variables provided' do
24
+ expect(uri.expand(id: 123))
25
+ .to eql 'http://www.host.com/shops/123/'
26
+ end
27
+
28
+ it 'complains if passing undeclared params' do
29
+ expect{
30
+ uri.expand(id: 123, nope: 'nope')
31
+ }.to raise_error BooticClient::InvalidURLError
32
+ end
33
+
34
+ it 'understand variable lists in query' do
35
+ uri = described_class.new('http://www.host.com/shops{/id}/{?foo,bar}')
36
+ expect{
37
+ uri.expand(id: 123, foo: 'foo', bar: 'bar', nope: 'nope')
38
+ }.to raise_error BooticClient::InvalidURLError
39
+ end
40
+
41
+ it 'expands if passing declared query variables' do
42
+ expect(uri.expand(id: 123, foo: 'yes'))
43
+ .to eql 'http://www.host.com/shops/123/?foo=yes'
44
+ end
45
+
46
+ it 'expands if passing declared query variables defined as list' do
47
+ uri = described_class.new('http://www.host.com/shops{/id}/{?foo,bar}')
48
+ expect(uri.expand(id: 123, foo: 'yes', bar: 'no'))
49
+ .to eql 'http://www.host.com/shops/123/?foo=yes&bar=no'
50
+ end
51
+ end
52
+ end
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.18
4
+ version: 0.0.19
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ismael Celis
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-04-03 00:00:00.000000000 Z
11
+ date: 2017-06-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -194,6 +194,7 @@ files:
194
194
  - lib/bootic_client/strategies/oauth2_strategy.rb
195
195
  - lib/bootic_client/strategies/strategy.rb
196
196
  - lib/bootic_client/version.rb
197
+ - lib/bootic_client/whiny_uri.rb
197
198
  - spec/authorized_strategy_spec.rb
198
199
  - spec/basic_auth_strategy_spec.rb
199
200
  - spec/bearer_strategy_spec.rb
@@ -205,6 +206,7 @@ files:
205
206
  - spec/memcache_storage_spec.rb
206
207
  - spec/relation_spec.rb
207
208
  - spec/spec_helper.rb
209
+ - spec/whiny_uri_spec.rb
208
210
  homepage: https://developers.bootic.net
209
211
  licenses:
210
212
  - MIT
@@ -241,3 +243,4 @@ test_files:
241
243
  - spec/memcache_storage_spec.rb
242
244
  - spec/relation_spec.rb
243
245
  - spec/spec_helper.rb
246
+ - spec/whiny_uri_spec.rb