bootic_client 0.0.18 → 0.0.19

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