graphlient 0.3.7 → 0.5.0

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: ab92f3273bda224b78e022567186f00e9865d746ecb9de61d6ae392e480bc67d
4
- data.tar.gz: 4e56127d81400beb61d1b9f502b63b3a712aa976d723dba524cbb6e579a7711b
3
+ metadata.gz: c049e978a0c48e45fe84d49470bc890ae3b6ea86b86aab8158322616c62968dd
4
+ data.tar.gz: c7307c2b5c6ac6ac2b55ee4d416bbfffee1e29ed0826916254077add10370ee9
5
5
  SHA512:
6
- metadata.gz: 0480cf615f51cd10d7c74efe03b0a291870027373cd9b4d5d3ee55b778ec4494379177823e1864f7d5c77da7c71eaead5a9870127a0976c9ba5ff0e84bbe9877
7
- data.tar.gz: 73202625813b08c871393e7656412a2439caf4454e8d021c00fcd24e06cca47328bee530571e013e0e69fba217cbc284fa187ae0661f3e495eeb65e14995f6b4
6
+ metadata.gz: 627d0d04d5ecea5e4c33ea0e59b15ac46fc458f76f179ac624d3519036865ad29267f629b1b3fda7592a50c846ea2cf06cc58a8f188a06caee44715268c18d07
7
+ data.tar.gz: 9742adef6879fbd08b00350674dced4b4886e476b45388d6d1a1afaaebba440153632e878649ff68beb223b158f365dd180b6db76e8463a13dbbeb4cdf8aa88d
data/.rubocop.yml CHANGED
@@ -1,3 +1,9 @@
1
+ AllCops:
2
+ TargetRubyVersion: 2.3
3
+
4
+ Lint/SplatKeywordArguments:
5
+ Enabled: false
6
+
1
7
  Style/FrozenStringLiteralComment:
2
8
  Enabled: false
3
9
 
data/.travis.yml CHANGED
@@ -3,9 +3,9 @@ language: ruby
3
3
  cache: bundler
4
4
 
5
5
  rvm:
6
- - 2.3.6
7
- - 2.4.3
8
6
  - 2.5.0
7
+ - 2.7.2
8
+ - 3.0.0
9
9
  - ruby-head
10
10
  - jruby-9.1.16.0
11
11
  - jruby-head
@@ -15,7 +15,7 @@ before_install:
15
15
 
16
16
  matrix:
17
17
  include:
18
- - rvm: 2.3.6
18
+ - rvm: 2.7.2
19
19
  script:
20
20
  - bundle exec danger
21
21
  allow_failures:
data/CHANGELOG.md CHANGED
@@ -1,7 +1,20 @@
1
- ### 0.3.8 (Next)
1
+ ### 0.6.0 (Next)
2
2
  * Your contribution here.
3
3
 
4
- ### 0.3.7 (14/11/2019)
4
+ ### 0.5.0 (12/28/2020)
5
+
6
+ * [#81](https://github.com/ashkan18/graphlient/pull/81): Make graphlient run on ruby 3.0 - [@Burgestrand](https://github.com/Burgestrand).
7
+ * [#79](https://github.com/ashkan18/graphlient/pull/79): Added client testing docs - [@GabrielDzul](https://github.com/GabrielDzul).
8
+
9
+ ### 0.4.0 (5/22/2020)
10
+
11
+ * [#72](https://github.com/ashkan18/graphlient/pull/72): Add http_options - [@neroleung](https://github.com/neroleung).
12
+ * [#71](https://github.com/ashkan18/graphlient/issues/70): Add `Graphlient::Errors::TimeoutError` - [@BenDrozdoff](https://github.com/BenDrozdoff).
13
+ * [#75](https://github.com/ashkan18/graphlient/pull/75): Support Faraday 1.x - [@jfhinchcliffe](https://github.com/jfhinchcliffe).
14
+ * [#78](https://github.com/ashkan18/graphlient/pull/78): Add description of timeout values - [@sap1enza](https://github.com/sap1enza).
15
+
16
+ ### 0.3.7 (11/14/2019)
17
+
5
18
  * [#68](https://github.com/ashkan18/graphlient/pull/68): Add `Graphlient::Errors::ConnectionFailedError` - [@neroleung](https://github.com/neroleung).
6
19
 
7
20
  ### 0.3.6 (07/23/2019)
data/Gemfile CHANGED
@@ -15,7 +15,7 @@ group :development do
15
15
  end
16
16
 
17
17
  group :test do
18
- gem 'graphql', '~> 1.9.7'
18
+ gem 'graphql', '~> 1.9'
19
19
  gem 'graphql-errors'
20
20
  gem 'rack-parser'
21
21
  gem 'rack-test'
data/README.md CHANGED
@@ -15,16 +15,25 @@ gem 'graphlient'
15
15
 
16
16
  ## Usage
17
17
 
18
- Create a new instance of `Graphlient::Client` with a URL and optional headers.
18
+ Create a new instance of `Graphlient::Client` with a URL and optional headers/http_options.
19
19
 
20
20
  ```ruby
21
21
  client = Graphlient::Client.new('https://test-graphql.biz/graphql',
22
22
  headers: {
23
23
  'Authorization' => 'Bearer 123'
24
+ },
25
+ http_options: {
26
+ read_timeout: 20,
27
+ write_timeout: 30
24
28
  }
25
29
  )
26
30
  ```
27
31
 
32
+ | http_options | default | type |
33
+ |---------------|---------|---------|
34
+ | read_timeout | nil | seconds |
35
+ | write_timeout | nil | seconds |
36
+
28
37
  The schema is available automatically via `.schema`.
29
38
 
30
39
  ```ruby
@@ -127,6 +136,8 @@ Unlike graphql-client, Graphlient will always raise an exception unless the quer
127
136
  * [Graphlient::Errors::FaradayServerError](lib/graphlient/errors/faraday_server_error.rb): this inherits from `ServerError` ☝️, we recommend using `ServerError` to rescue these
128
137
  * [Graphlient::Errors::HttpServerError](lib/graphlient/errors/http_server_error.rb): this inherits from `ServerError` ☝️, we recommend using `ServerError` to rescue these
129
138
  * [Graphlient::Errors::ConnectionFailedError](lib/graphlient/errors/connection_failed_error.rb): this inherits from `ServerError` ☝️, we recommend using `ServerError` to rescue these
139
+ * [Graphlient::Errors::TimeoutError](lib/graphlient/errors/timeout_error.rb): this inherits from `ServerError` ☝️, we recommend using `ServerError` to rescue these
140
+ * [Graphlient::Errors::HttpOptionsError](lib/graphlient/errors/http_options_error.rb): all NoMethodError raised by HTTP Adapters when given options in `http_options` are invalid
130
141
 
131
142
 
132
143
  All errors inherit from `Graphlient::Errors::Error` if you need to handle them in bulk.
@@ -334,7 +345,7 @@ describe App do
334
345
  Graphlient::Client.new('http://test-graphql.biz/graphql') do |client|
335
346
  client.http do |h|
336
347
  h.connection do |c|
337
- c.use Faraday::Adapter::Rack, app
348
+ c.adapter Faraday::Adapter::Rack, app
338
349
  end
339
350
  end
340
351
  end
@@ -378,6 +389,49 @@ describe App do
378
389
  end
379
390
  ```
380
391
 
392
+ In order to stub the response to actual queries, [dump the schema into a JSON file](#schema-storing-and-loading-on-disk) and specify it via schema_path as follows.
393
+
394
+ ```ruby
395
+ describe App do
396
+ let(:url) { 'http://graph.biz/graphql' }
397
+ let(:client) { Graphlient::Client.new(url, schema_path: 'spec/support/fixtures/invoice_api.json') }
398
+ let(:query) do
399
+ <<~GRAPHQL
400
+ query{
401
+ invoice(id: 42) {
402
+ id
403
+ feeInCents
404
+ }
405
+ }
406
+ GRAPHQL
407
+ end
408
+ let(:json_response) do
409
+ {
410
+ 'data' => {
411
+ 'invoice' => {
412
+ 'id' => '42',
413
+ 'feeInCents' => 2000
414
+ }
415
+ }
416
+ }.to_json
417
+ end
418
+
419
+ before do
420
+ stub_request(:post, url).to_return(
421
+ status: 200,
422
+ body: json_response
423
+ )
424
+ end
425
+
426
+ it 'returns invoice fees' do
427
+ response = client.query(query)
428
+ expect(response.data).to be_truthy
429
+ expect(response.data.invoice.id).to eq('42')
430
+ expect(response.data.invoice.fee_in_cents).to eq(2000)
431
+ end
432
+ end
433
+ ```
434
+
381
435
  ## License
382
436
 
383
437
  MIT License, see [LICENSE](LICENSE)
data/UPGRADING.md CHANGED
@@ -1,6 +1,17 @@
1
1
  Upgrading Graphlient
2
2
  ===========================
3
3
 
4
+ ### Upgrading to >= 0.4.0
5
+
6
+ #### Requires Faraday >= 1.0
7
+
8
+ See [#75](https://github.com/ashkan18/graphlient/pull/75).
9
+
10
+ #### Changes in error handling of connection refused error
11
+
12
+ When the GraphQL request was failing, we were receiving a `Faraday::ServerError`. After 0.4.0, Graphlient
13
+ will return `Graphlient::Errors::FaradayServerError` instead.
14
+
4
15
  ### Upgrading to >= 0.3.7
5
16
 
6
17
  #### Changes in error handling of connection refused error
data/graphlient.gemspec CHANGED
@@ -14,7 +14,7 @@ Gem::Specification.new do |s|
14
14
  s.homepage = 'http://github.com/ashkan18/graphlient'
15
15
  s.licenses = ['MIT']
16
16
  s.summary = 'A friendlier Ruby client for consuming GraphQL-based APIs.'
17
- s.add_dependency 'faraday'
17
+ s.add_dependency 'faraday', '>= 1.0'
18
18
  s.add_dependency 'faraday_middleware'
19
19
  s.add_dependency 'graphql-client'
20
20
  end
@@ -14,9 +14,27 @@ module Graphlient
14
14
  options[:headers] if options
15
15
  end
16
16
 
17
+ def http_options
18
+ return {} unless options
19
+
20
+ options[:http_options] || {}
21
+ end
22
+
17
23
  def execute(*)
18
24
  raise NotImplementedError
19
25
  end
26
+
27
+ private
28
+
29
+ def configure_http_options(client_options)
30
+ http_options.each do |k, v|
31
+ begin
32
+ client_options.send("#{k}=", v)
33
+ rescue NoMethodError => e
34
+ raise Graphlient::Errors::HttpOptionsError, e.message
35
+ end
36
+ end
37
+ end
20
38
  end
21
39
  end
22
40
  end
@@ -17,8 +17,12 @@ module Graphlient
17
17
  response.body
18
18
  rescue Faraday::ConnectionFailed => e
19
19
  raise Graphlient::Errors::ConnectionFailedError, e
20
+ rescue Faraday::TimeoutError => e
21
+ raise Graphlient::Errors::TimeoutError, e
20
22
  rescue Faraday::ClientError => e
21
23
  raise Graphlient::Errors::FaradayServerError, e
24
+ rescue Faraday::ServerError => e
25
+ raise Graphlient::Errors::FaradayServerError, e
22
26
  end
23
27
 
24
28
  def connection
@@ -26,10 +30,13 @@ module Graphlient
26
30
  c.use Faraday::Response::RaiseError
27
31
  c.request :json
28
32
  c.response :json
33
+
34
+ configure_http_options(c.options)
35
+
29
36
  if block_given?
30
37
  yield c
31
38
  else
32
- c.use Faraday::Adapter::NetHttp
39
+ c.adapter Faraday::Adapter::NetHttp
33
40
  end
34
41
  end
35
42
  end
@@ -29,6 +29,8 @@ module Graphlient
29
29
  def connection
30
30
  Net::HTTP.new(uri.host, uri.port).tap do |client|
31
31
  client.use_ssl = uri.scheme == 'https'
32
+
33
+ configure_http_options(client)
32
34
  end
33
35
  end
34
36
  end
@@ -22,7 +22,7 @@ module Graphlient
22
22
  query_params[:context] = @options if @options
23
23
  query_params[:variables] = variables if variables
24
24
  query = client.parse(query) if query.is_a?(String)
25
- rc = client.query(query, query_params)
25
+ rc = client.query(query, **query_params)
26
26
  raise Graphlient::Errors::GraphQLError, rc if rc.errors.any?
27
27
  # see https://github.com/github/graphql-client/pull/132
28
28
  # see https://github.com/exAspArk/graphql-errors/issues/2
@@ -45,7 +45,9 @@ module Graphlient
45
45
  end
46
46
 
47
47
  def http(&block)
48
- @http ||= http_adapter_class.new(@url, headers: @options[:headers], &block)
48
+ adapter_options = { headers: @options[:headers], http_options: @options[:http_options] }
49
+
50
+ @http ||= http_adapter_class.new(@url, adapter_options, &block)
49
51
  end
50
52
 
51
53
  def schema
@@ -0,0 +1,6 @@
1
+ module Graphlient
2
+ module Errors
3
+ class HttpOptionsError < Error
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ module Graphlient
2
+ module Errors
3
+ class TimeoutError < Error
4
+ end
5
+ end
6
+ end
@@ -4,5 +4,7 @@ require_relative 'errors/server_error'
4
4
  require_relative 'errors/graphql_error'
5
5
  require_relative 'errors/execution_error'
6
6
  require_relative 'errors/faraday_server_error'
7
+ require_relative 'errors/http_options_error'
7
8
  require_relative 'errors/http_server_error'
8
9
  require_relative 'errors/connection_failed_error'
10
+ require_relative 'errors/timeout_error'
@@ -1,3 +1,3 @@
1
1
  module Graphlient
2
- VERSION = '0.3.7'.freeze
2
+ VERSION = '0.5.0'.freeze
3
3
  end
@@ -8,29 +8,32 @@ describe Graphlient::Adapters::HTTP::FaradayAdapter do
8
8
  Graphlient::Client.new('http://example.com/graphql') do |client|
9
9
  client.http do |h|
10
10
  h.connection do |c|
11
- c.use Faraday::Adapter::Rack, app
11
+ c.adapter Faraday::Adapter::Rack, app
12
12
  end
13
13
  end
14
14
  end
15
15
  end
16
16
 
17
17
  it 'inserts a middleware into the connection' do
18
+ expect(client.http.connection.adapter).to eq Faraday::Adapter::Rack
18
19
  expect(client.http.connection.builder.handlers).to eq(
19
20
  [
20
21
  Faraday::Response::RaiseError,
21
22
  FaradayMiddleware::EncodeJson,
22
- FaradayMiddleware::ParseJson,
23
- Faraday::Adapter::Rack
23
+ FaradayMiddleware::ParseJson
24
24
  ]
25
25
  )
26
26
  end
27
27
  end
28
28
 
29
- context 'with custom url and headers' do
29
+ context 'with custom url, headers and http_options' do
30
30
  let(:url) { 'http://example.com/graphql' }
31
31
  let(:headers) { { 'Foo' => 'bar' } }
32
+ let(:http_options) { { timeout: timeout, write_timeout: write_timeout } }
33
+ let(:timeout) { 123 }
34
+ let(:write_timeout) { 234 }
32
35
  let(:client) do
33
- Graphlient::Client.new(url, headers: headers)
36
+ Graphlient::Client.new(url, headers: headers, http_options: http_options)
34
37
  end
35
38
 
36
39
  it 'sets url' do
@@ -40,6 +43,19 @@ describe Graphlient::Adapters::HTTP::FaradayAdapter do
40
43
  it 'sets headers' do
41
44
  expect(client.http.headers).to eq headers
42
45
  end
46
+
47
+ it 'sets http_options' do
48
+ expect(client.http.connection.options.timeout).to eq(timeout)
49
+ expect(client.http.connection.options.write_timeout).to eq(write_timeout)
50
+ end
51
+
52
+ context 'when http_options contains invalid option' do
53
+ let(:http_options) { { an_invalid_option: 'an invalid option' } }
54
+
55
+ it 'raises Graphlient::Errors::HttpOptionsError' do
56
+ expect { client.http.connection }.to raise_error(Graphlient::Errors::HttpOptionsError)
57
+ end
58
+ end
43
59
  end
44
60
 
45
61
  context 'default' do
@@ -78,4 +94,19 @@ describe Graphlient::Adapters::HTTP::FaradayAdapter do
78
94
  expect { client.schema }.to raise_error(Graphlient::Errors::ConnectionFailedError, expected_error_message)
79
95
  end
80
96
  end
97
+
98
+ context 'Faraday Timeout Error' do
99
+ let(:url) { 'http://example.com/graphql' }
100
+ let(:client) { Graphlient::Client.new(url) }
101
+ let(:error_message) { 'Failed to Connect' }
102
+
103
+ before do
104
+ stub_request(:post, url).to_raise(Faraday::TimeoutError.new(Net::ReadTimeout.new(error_message)))
105
+ end
106
+ it 'raises a Graphlient Timeout' do
107
+ expect { client.schema }.to raise_error(Graphlient::Errors::TimeoutError) { |error|
108
+ expect(error.message).to include(error_message)
109
+ }
110
+ end
111
+ end
81
112
  end
@@ -3,11 +3,18 @@ require 'spec_helper'
3
3
  describe Graphlient::Adapters::HTTP::HTTPAdapter do
4
4
  let(:app) { Object.new }
5
5
 
6
- context 'with custom url and headers' do
6
+ context 'with custom url, headers and http_options' do
7
7
  let(:url) { 'http://example.com/graphql' }
8
8
  let(:headers) { { 'Foo' => 'bar' } }
9
+ let(:http_options) { { read_timeout: read_timeout } }
10
+ let(:read_timeout) { nil }
9
11
  let(:client) do
10
- Graphlient::Client.new(url, headers: headers, http: Graphlient::Adapters::HTTP::HTTPAdapter)
12
+ Graphlient::Client.new(
13
+ url,
14
+ headers: headers,
15
+ http_options: http_options,
16
+ http: Graphlient::Adapters::HTTP::HTTPAdapter
17
+ )
11
18
  end
12
19
 
13
20
  it 'sets adapter' do
@@ -21,6 +28,18 @@ describe Graphlient::Adapters::HTTP::HTTPAdapter do
21
28
  it 'sets headers' do
22
29
  expect(client.http.headers).to eq headers
23
30
  end
31
+
32
+ it 'sets http_options' do
33
+ expect(client.http.connection.read_timeout).to eq(read_timeout)
34
+ end
35
+
36
+ context 'when http_options contains invalid option' do
37
+ let(:http_options) { { an_invalid_option: 'an invalid option' } }
38
+
39
+ it 'raises Graphlient::Errors::HttpOptionsError' do
40
+ expect { client.http.connection }.to raise_error(Graphlient::Errors::HttpOptionsError)
41
+ end
42
+ end
24
43
  end
25
44
 
26
45
  context 'default' do
@@ -91,7 +91,7 @@ describe Graphlient::Client do
91
91
  expect do
92
92
  client.execute(query, id: '42')
93
93
  end.to raise_error Graphlient::Errors::GraphQLError do |e|
94
- expect(e.to_s).to eq 'Variable id of type Int was provided invalid value'
94
+ expect(e.to_s).to eq 'Variable $id of type Int was provided invalid value'
95
95
  end
96
96
  end
97
97
 
@@ -223,7 +223,7 @@ describe Graphlient::Client do
223
223
  end
224
224
  end
225
225
  end.to raise_error Graphlient::Errors::GraphQLError,
226
- 'Variable input of type CreateInvoiceInput! was provided invalid value'
226
+ 'Variable $input of type CreateInvoiceInput! was provided invalid value'
227
227
  end
228
228
 
229
229
  it 'returns a response from a query' do
@@ -272,7 +272,7 @@ describe Graphlient::Client do
272
272
  end
273
273
  end
274
274
  end.to raise_error Graphlient::Errors::GraphQLError,
275
- 'Variable input of type CreateInvoiceInput! was provided invalid value for feeInCents (Expected value to not be null)'
275
+ 'Variable $input of type CreateInvoiceInput! was provided invalid value for feeInCents (Expected value to not be null)'
276
276
  end
277
277
  end
278
278
  end
@@ -19,7 +19,7 @@ describe Graphlient::Client do
19
19
  it 'fails with an exception' do
20
20
  expect do
21
21
  client.schema
22
- end.to raise_error Graphlient::Errors::ServerError do |e|
22
+ end.to raise_error Graphlient::Errors::FaradayServerError do |e|
23
23
  expect(e.to_s).to eq 'the server responded with status 500'
24
24
  expect(e.status_code).to eq 500
25
25
  expect(e.response['errors'].size).to eq 1
@@ -10,7 +10,7 @@ describe Graphlient::Client do
10
10
  ) do |client|
11
11
  client.http do |h|
12
12
  h.connection do |c|
13
- c.use Faraday::Adapter::Rack, Sinatra::Application
13
+ c.adapter Faraday::Adapter::Rack, Sinatra::Application
14
14
  end
15
15
  end
16
16
  end
@@ -0,0 +1,40 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'App' do
4
+ let(:url) { 'http://graph.biz/graphql' }
5
+ let(:client) { Graphlient::Client.new(url, schema_path: 'spec/support/fixtures/invoice_api.json') }
6
+ let(:query) do
7
+ <<~GRAPHQL
8
+ query{
9
+ invoice(id: 42) {
10
+ id
11
+ feeInCents
12
+ }
13
+ }
14
+ GRAPHQL
15
+ end
16
+ let(:json_response) do
17
+ {
18
+ 'data' => {
19
+ 'invoice' => {
20
+ 'id' => '42',
21
+ 'feeInCents' => 2000
22
+ }
23
+ }
24
+ }.to_json
25
+ end
26
+
27
+ before do
28
+ stub_request(:post, url).to_return(
29
+ status: 200,
30
+ body: json_response
31
+ )
32
+ end
33
+
34
+ it 'returns invoice fees' do
35
+ response = client.query(query)
36
+ expect(response.data).to be_truthy
37
+ expect(response.data.invoice.id).to eq('42')
38
+ expect(response.data.invoice.fee_in_cents).to eq(2000)
39
+ end
40
+ end
@@ -18,7 +18,7 @@ RSpec.shared_context 'Dummy Client', shared_context: :metadata do
18
18
  Graphlient::Client.new(endpoint, headers: headers) do |client|
19
19
  client.http do |h|
20
20
  h.connection do |c|
21
- c.use Faraday::Adapter::Rack, app
21
+ c.adapter Faraday::Adapter::Rack, app
22
22
  end
23
23
  end
24
24
  end