hyperclient 0.9.1 → 1.0.1

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
  SHA256:
3
- metadata.gz: 494b4be638b3b6d76edd4d07e5b12e36433dfd84c9a756dec34a278fd9ea2faa
4
- data.tar.gz: 1d9e97e2a76cdf4a991a5803bd14eadf40ae300e4065cbacdedee64b66f19a3c
3
+ metadata.gz: 5f55cb82362d8eca25347e15c91387bbf2957f1f1241af27fccff1086b412d1b
4
+ data.tar.gz: f31325a293b0aec888b94910b8c3dc28d2f30a6666fe59063b4112251f46e7c4
5
5
  SHA512:
6
- metadata.gz: bd401bb429c28fb75af0c95908deaa43f91a67923c47ba17ba369eb238252add1657ea1aa2b57f9721c59113c06d394274268ade288618314b93c7d4e0c11b31
7
- data.tar.gz: 5892d3cabd8bad2e6bd5c6e9a5c6ef7f3fa9f7376c6aa39e9225acf8c37160da3550b66ff420440a9565d29ea898784bd3093bd36b09cbf1302f45aaa7d0a5a6
6
+ metadata.gz: e9b17e112614d3c600497c6c7cfd56268195427da789629d006742ff96e70d2b6972ba16fbfa075ab62613eeace923d8fdb4f231b9d86a04f82b75fa5d4a4826
7
+ data.tar.gz: 8a8861e266967702c86d5762ec5b786687298c37e797a5c324583c9d3c9d2fe4dc83cf8841c912db3d14a0bf731d1dbee0c1c85b3d43961589c5741b43b3f128
data/.rubocop.yml CHANGED
@@ -3,8 +3,8 @@ inherit_from: .rubocop_todo.yml
3
3
  AllCops:
4
4
  TargetRubyVersion: 2.3
5
5
 
6
- Metrics/BlockLength:
7
- ExcludedMethods: [it, describe]
6
+ Metrics:
7
+ Enabled: false
8
8
 
9
9
  Style/FrozenStringLiteralComment:
10
- Enabled: false
10
+ Enabled: false
data/.rubocop_todo.yml CHANGED
@@ -1,26 +1,11 @@
1
1
  # This configuration was generated by
2
2
  # `rubocop --auto-gen-config`
3
- # on 2019-08-25 11:12:51 -0400 using RuboCop version 0.74.0.
3
+ # on 2020-12-03 14:08:14 -0500 using RuboCop version 0.81.0.
4
4
  # The point is for the user to remove these configuration records
5
5
  # one by one as the offenses are removed from the code base.
6
6
  # Note that changes in the inspected code, or installation of new
7
7
  # versions of RuboCop, may require this file to be generated again.
8
8
 
9
- # Offense count: 1
10
- # Configuration parameters: CountComments.
11
- Metrics/ClassLength:
12
- Max: 103
13
-
14
- # Offense count: 3
15
- # Configuration parameters: CountComments, ExcludedMethods.
16
- Metrics/MethodLength:
17
- Max: 25
18
-
19
- # Offense count: 3
20
- # Configuration parameters: CountComments.
21
- Metrics/ModuleLength:
22
- Max: 265
23
-
24
9
  # Offense count: 2
25
10
  # Cop supports --auto-correct.
26
11
  # Configuration parameters: AutoCorrect, EnforcedStyle.
@@ -46,14 +31,22 @@ Style/DoubleNegation:
46
31
  - 'lib/hyperclient/curie.rb'
47
32
  - 'lib/hyperclient/link.rb'
48
33
 
34
+ # Offense count: 3
35
+ # Cop supports --auto-correct.
36
+ Style/IfUnlessModifier:
37
+ Exclude:
38
+ - 'lib/hyperclient/link_collection.rb'
39
+ - 'lib/hyperclient/resource.rb'
40
+ - 'lib/hyperclient/resource_collection.rb'
41
+
49
42
  # Offense count: 1
50
43
  Style/MethodMissingSuper:
51
44
  Exclude:
52
45
  - 'lib/hyperclient/collection.rb'
53
46
 
54
- # Offense count: 93
47
+ # Offense count: 101
55
48
  # Cop supports --auto-correct.
56
49
  # Configuration parameters: AutoCorrect, AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
57
50
  # URISchemes: http, https
58
- Metrics/LineLength:
59
- Max: 142
51
+ Layout/LineLength:
52
+ Max: 147
data/.travis.yml CHANGED
@@ -4,22 +4,21 @@ sudo: false
4
4
 
5
5
  matrix:
6
6
  include:
7
- - rvm: 2.6.3
8
- - rvm: 2.5.5
9
- - rvm: 2.4.6
10
- - rvm: 2.4.6
7
+ - rvm: 2.6.6
8
+ env: FARADAY_VERSION=0.9.0
9
+ - rvm: 2.6.6
10
+ env: FARADAY_VERSION=0.17.0
11
+ - rvm: 2.6.6
12
+ env: FARADAY_VERSION="~> 1.0"
13
+ - rvm: 2.6.6
11
14
  script:
12
15
  - bundle exec danger
16
+ - rvm: 2.3.8
13
17
  - rvm: jruby-9.2.7.0
14
18
  - rvm: jruby-head
15
- - rvm: 2.3.8
16
19
  - rvm: ruby-head
17
20
  allow_failures:
18
21
  - rvm: ruby-head
19
22
  - rvm: jruby-head
20
23
 
21
- before_install:
22
- - gem update --system
23
- - gem install bundler
24
-
25
24
  bundler_args: --without development
data/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  ## Changelog
2
2
 
3
+ ### 1.0.1 (2021/01/02)
4
+
5
+ * [#193](https://github.com/codegram/hyperclient/pull/193): Auto-paginate collections - [@dblock](https://github.com/dblock).
6
+ * [#163](https://github.com/codegram/hyperclient/pull/163): Test against Faraday 0.9, 0.17 and 1.0+ - [@dblock](https://github.com/dblock).
7
+ * [#199](https://github.com/codegram/hyperclient/pull/199): Use digest_auth from faraday-digestauth - [@dblock](https://github.com/dblock).
8
+
9
+ ### 1.0.0 (2021/01/02)
10
+
11
+ * NOTE: **⚠ This version has been yanked ⚠** - [@dblock](https://github.com/dblock).
12
+
13
+ ### 0.9.3 (2020/05/14)
14
+
15
+ * [#149](https://github.com/codegram/hyperclient/pull/149): Address Faraday warnings - [@yuki24](https://github.com/yuki24).
16
+ * [#160](https://github.com/codegram/hyperclient/pull/160): Require newer 'faraday-digestauth' - [@dblock](https://github.com/dblock).
17
+
18
+ ### 0.9.2 (2020/05/12)
19
+
20
+ * NOTE: **⚠ This version has been yanked ⚠** - [@dblock](https://github.com/dblock).
21
+
3
22
  ### 0.9.1 (2019/08/25)
4
23
 
5
24
  * NOTE: **⚠ This version is no longer tested with Ruby < 2.3 ⚠** - [@ivoanjo](https://github.com/ivoanjo).
data/Gemfile CHANGED
@@ -3,6 +3,8 @@ git_source(:github) { |repo| "https://github.com/#{repo['/'] ? repo : "#{repo}/#
3
3
 
4
4
  source 'https://rubygems.org'
5
5
 
6
+ gem 'faraday', ENV['FARADAY_VERSION'] if ENV.key?('FARADAY_VERSION')
7
+
6
8
  gemspec
7
9
 
8
10
  group :development do
@@ -16,7 +18,7 @@ end
16
18
 
17
19
  group :development, :test do
18
20
  gem 'rake'
19
- gem 'rubocop', '~> 0.74.0', require: false
21
+ gem 'rubocop', '0.81.0', require: false
20
22
  gem 'simplecov', require: false
21
23
  end
22
24
 
data/README.md CHANGED
@@ -2,7 +2,6 @@
2
2
 
3
3
  [![Gem Version](http://img.shields.io/gem/v/hyperclient.svg)](http://badge.fury.io/rb/hyperclient)
4
4
  [![Build Status](http://img.shields.io/travis/codegram/hyperclient.svg)](https://travis-ci.org/codegram/hyperclient)
5
- [![Dependency Status](https://gemnasium.com/codegram/hyperclient.svg)](https://gemnasium.com/codegram/hyperclient)
6
5
  [![Code Climate](https://codeclimate.com/github/codegram/hyperclient.svg)](https://codeclimate.com/github/codegram/hyperclient)
7
6
  [![Coverage Status](https://img.shields.io/coveralls/codegram/hyperclient.svg)](https://coveralls.io/r/codegram/hyperclient?branch=master)
8
7
 
@@ -86,12 +85,19 @@ api = Hyperclient.new('https://grape-with-roar.herokuapp.com/api') do |client|
86
85
  end
87
86
  ```
88
87
 
89
- You can modify headers or specify authentication after a connection has been created. Hyperclient supports Basic, Token or Digest auth as well as many other Faraday extensions.
88
+ You can modify headers or specify authentication after a connection has been created. Hyperclient supports Basic, Token or [Digest auth](https://github.com/bhaberer/faraday-digestauth) as well as many other Faraday extensions.
90
89
 
91
90
  ```ruby
92
- api = Hyperclient.new('https://grape-with-roar.herokuapp.com/api')
93
- api.digest_auth('username', 'password')
94
- api.headers.update('Accept-Encoding' => 'deflate, gzip')
91
+ require 'faraday/digestauth'
92
+
93
+ api = Hyperclient.new('https://grape-with-roar.herokuapp.com/api') do |client|
94
+ client.connection(default: false) do |conn|
95
+ conn.request :digest, 'username', 'password'
96
+ conn.request :json
97
+ conn.response :json, content_type: /\bjson$/
98
+ conn.adapter :net_http
99
+ end
100
+ end
95
101
  ```
96
102
 
97
103
  You can access the Faraday connection directly after it has been created and add middleware to it. As an example, you could use the [faraday-http-cache-middleware](https://github.com/plataformatec/faraday-http-cache).
@@ -103,7 +109,7 @@ api.connection.use :http_cache
103
109
 
104
110
  ## Resources and Attributes
105
111
 
106
- Hyperclient will fetch and discover the resources from your API.
112
+ Hyperclient will fetch and discover the resources from your API and automatically paginate when possible.
107
113
 
108
114
  ```ruby
109
115
  api.splines.each do |spline|
@@ -7,6 +7,11 @@ Feature: API navigation
7
7
  When I connect to the API
8
8
  Then I should be able to navigate to posts and authors
9
9
 
10
+ Scenario: Links
11
+ When I connect to the API
12
+ Then I should be able to paginate posts
13
+ Then I should be able to paginate authors
14
+
10
15
  Scenario: Templated links
11
16
  Given I connect to the API
12
17
  When I search for a post with a templated link
@@ -9,6 +9,19 @@ class Spinach::Features::ApiNavigation < Spinach::FeatureSteps
9
9
  assert_requested :get, 'http://api.example.org/authors'
10
10
  end
11
11
 
12
+ step 'I should be able to paginate posts' do
13
+ assert_kind_of Enumerator, api.posts.each
14
+ assert_equal 4, api.posts.to_a.count
15
+ assert_requested :get, 'http://api.example.org/posts'
16
+ assert_requested :get, 'http://api.example.org/posts?page=2'
17
+ assert_requested :get, 'http://api.example.org/posts?page=3'
18
+ end
19
+
20
+ step 'I should be able to paginate authors' do
21
+ assert_equal 1, api._links['api:authors'].to_a.count
22
+ assert_requested :get, 'http://api.example.org/authors'
23
+ end
24
+
12
25
  step 'I search for a post with a templated link' do
13
26
  api._links.search._expand(q: 'something')._resource
14
27
  end
@@ -50,8 +63,8 @@ class Spinach::Features::ApiNavigation < Spinach::FeatureSteps
50
63
  step 'I should be able to count embedded items' do
51
64
  assert_equal 2, api._links.posts._resource._embedded.posts.count
52
65
  assert_equal 2, api.posts._embedded.posts.count
53
- assert_equal 2, api.posts.count
54
- assert_equal 2, api.posts.map.count
66
+ assert_equal 4, api.posts.count
67
+ assert_equal 4, api.posts.map.count
55
68
  end
56
69
 
57
70
  step 'I should be able to iterate over embedded items' do
@@ -59,6 +72,6 @@ class Spinach::Features::ApiNavigation < Spinach::FeatureSteps
59
72
  api.posts.each do |_post|
60
73
  count += 1
61
74
  end
62
- assert_equal 2, count
75
+ assert_equal 4, count
63
76
  end
64
77
  end
@@ -25,7 +25,7 @@ class Spinach::Features::DefaultConfig < Spinach::FeatureSteps
25
25
  end
26
26
 
27
27
  step 'it should have been parsed as JSON' do
28
- @posts._attributes.total_posts.to_i.must_equal 2
29
- @posts._attributes['total_posts'].to_i.must_equal 2
28
+ @posts._attributes.total_posts.to_i.must_equal 4
29
+ @posts._attributes['total_posts'].to_i.must_equal 4
30
30
  end
31
31
  end
@@ -8,8 +8,14 @@ module API
8
8
  WebMock::Config.instance.query_values_notation = :flat_array
9
9
 
10
10
  stub_request(:any, /api.example.org*/).to_return(body: root_response, headers: { 'Content-Type' => 'application/hal+json' })
11
+ stub_request(:get, 'api.example.org').to_return(body: root_response, headers: { 'Content-Type' => 'application/hal+json' })
12
+ stub_request(:get, 'api.example.org/authors').to_return(body: authors_response, headers: { 'Content-Type' => 'application/hal+json' })
11
13
  stub_request(:get, 'api.example.org/posts').to_return(body: posts_response, headers: { 'Content-Type' => 'application/hal+json' })
12
- stub_request(:get, 'api.example.org/posts/1').to_return(body: post_response, headers: { 'Content-Type' => 'application/hal+json' })
14
+ stub_request(:get, 'api.example.org/posts?page=2').to_return(body: posts_page2_response, headers: { 'Content-Type' => 'application/hal+json' })
15
+ stub_request(:get, 'api.example.org/posts?page=3').to_return(body: posts_page3_response, headers: { 'Content-Type' => 'application/hal+json' })
16
+ stub_request(:get, 'api.example.org/posts/1').to_return(body: post1_response, headers: { 'Content-Type' => 'application/hal+json' })
17
+ stub_request(:get, 'api.example.org/posts/2').to_return(body: post2_response, headers: { 'Content-Type' => 'application/hal+json' })
18
+ stub_request(:get, 'api.example.org/posts/3').to_return(body: post3_response, headers: { 'Content-Type' => 'application/hal+json' })
13
19
  stub_request(:get, 'api.example.org/page2').to_return(body: page2_response, headers: { 'Content-Type' => 'application/hal+json' })
14
20
  stub_request(:get, 'api.example.org/page3').to_return(body: page3_response, headers: { 'Content-Type' => 'application/hal+json' })
15
21
  end
@@ -15,13 +15,32 @@ module Spinach
15
15
  }'
16
16
  end
17
17
 
18
+ def authors_response
19
+ '{
20
+ "_links": {
21
+ "self": { "href": "/authors" }
22
+ },
23
+ "_embedded": {
24
+ "api:authors": [
25
+ {
26
+ "name": "Lorem Ipsum",
27
+ "_links": {
28
+ "self": { "href": "/authors/1" }
29
+ }
30
+ }
31
+ ]
32
+ }
33
+ }'
34
+ end
35
+
18
36
  def posts_response
19
37
  '{
20
38
  "_links": {
21
39
  "self": { "href": "/posts" },
40
+ "next": {"href": "/posts?page=2"},
22
41
  "last_post": {"href": "/posts/1"}
23
42
  },
24
- "total_posts": "2",
43
+ "total_posts": "4",
25
44
  "_embedded": {
26
45
  "posts": [
27
46
  {
@@ -43,7 +62,48 @@ module Spinach
43
62
  }'
44
63
  end
45
64
 
46
- def post_response
65
+ def posts_page2_response
66
+ '{
67
+ "_links": {
68
+ "self": { "href": "/posts?page=2" },
69
+ "next": { "href": "/posts?page=3" }
70
+ },
71
+ "total_posts": "4",
72
+ "_embedded": {
73
+ "posts": [
74
+ {
75
+ "title": "My third blog post",
76
+ "body": "Lorem ipsum dolor sit amet",
77
+ "_links": {
78
+ "self": { "href": "/posts/3" }
79
+ }
80
+ }
81
+ ]
82
+ }
83
+ }'
84
+ end
85
+
86
+ def posts_page3_response
87
+ '{
88
+ "_links": {
89
+ "self": { "href": "/posts?page=3" }
90
+ },
91
+ "total_posts": "4",
92
+ "_embedded": {
93
+ "posts": [
94
+ {
95
+ "title": "My third blog post",
96
+ "body": "Lorem ipsum dolor sit amet",
97
+ "_links": {
98
+ "self": { "href": "/posts/4" }
99
+ }
100
+ }
101
+ ]
102
+ }
103
+ }'
104
+ end
105
+
106
+ def post1_response
47
107
  '{
48
108
  "_links": {
49
109
  "self": { "href": "/posts/1" }
@@ -60,6 +120,40 @@ module Spinach
60
120
  }'
61
121
  end
62
122
 
123
+ def post2_response
124
+ '{
125
+ "_links": {
126
+ "self": { "href": "/posts/2" }
127
+ },
128
+ "title": "My first blog post",
129
+ "body": "Lorem ipsum dolor sit amet",
130
+ "_embedded": {
131
+ "comments": [
132
+ {
133
+ "title": "Some comment"
134
+ }
135
+ ]
136
+ }
137
+ }'
138
+ end
139
+
140
+ def post3_response
141
+ '{
142
+ "_links": {
143
+ "self": { "href": "/posts/3" }
144
+ },
145
+ "title": "My first blog post",
146
+ "body": "Lorem ipsum dolor sit amet",
147
+ "_embedded": {
148
+ "comments": [
149
+ {
150
+ "title": "Some comment"
151
+ }
152
+ ]
153
+ }
154
+ }'
155
+ end
156
+
63
157
  def page2_response
64
158
  '{
65
159
  "_links": {
data/hyperclient.gemspec CHANGED
@@ -15,8 +15,6 @@ Gem::Specification.new do |gem|
15
15
 
16
16
  gem.add_dependency 'addressable'
17
17
  gem.add_dependency 'faraday', '>= 0.9.0'
18
- gem.add_dependency 'faraday-digestauth'
19
18
  gem.add_dependency 'faraday_hal_middleware'
20
19
  gem.add_dependency 'faraday_middleware'
21
- gem.add_dependency 'net-http-digest_auth'
22
20
  end
@@ -1,6 +1,5 @@
1
1
  require 'faraday_middleware'
2
2
  require 'faraday_hal_middleware'
3
- require_relative '../faraday/connection'
4
3
 
5
4
  module Hyperclient
6
5
  # Public: Exception that is raised when trying to modify an
@@ -30,7 +29,7 @@ module Hyperclient
30
29
  extend Forwardable
31
30
 
32
31
  # Public: Delegates common methods to be used with the Faraday connection.
33
- def_delegators :connection, :basic_auth, :digest_auth, :token_auth, :params, :params=
32
+ def_delegators :connection, :params, :params=
34
33
 
35
34
  # Public: Initializes an EntryPoint.
36
35
  #
@@ -62,8 +61,7 @@ module Hyperclient
62
61
  block
63
62
  else
64
63
  lambda do |conn|
65
- default_faraday_block.call conn
66
- yield conn
64
+ default_faraday_block.call(conn, &block)
67
65
  end
68
66
  end
69
67
  else
@@ -138,11 +136,14 @@ module Hyperclient
138
136
  #
139
137
  # Returns a block.
140
138
  def default_faraday_block
141
- lambda do |connection|
139
+ lambda do |connection, &block|
142
140
  connection.use Faraday::Response::RaiseError
143
141
  connection.use FaradayMiddleware::FollowRedirects
144
142
  connection.request :hal_json
145
143
  connection.response :hal_json, content_type: /\bjson$/
144
+
145
+ block&.call(connection)
146
+
146
147
  connection.adapter :net_http
147
148
  connection.options.params_encoder = Faraday::FlatParamsEncoder
148
149
  end