fulfil-io 0.4.8 → 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: 2ee812b819341ca5960284540853594c9ec4ec07735f75672913cbdce1e7bf72
4
- data.tar.gz: 01f68a856b317a9ccc00946bac7ce06e638e9d016bf075a7e4130d17420f7c8a
3
+ metadata.gz: 1100e113c9323c0fa742ece65d8a41923c060c382b1b97ad6c50ad20c550b5a9
4
+ data.tar.gz: 80535f7bea24218d958812bbd8e4ab789ce966c346e5dfa891369160fc04e536
5
5
  SHA512:
6
- metadata.gz: cb6a91114dea84e8c578f96ab2599ad03c036fc3222bf4b494f8cd32f79944b744660a2c0e4c7c45602e05e28f651eb6a6786a51e591950e04e36b291b3755a3
7
- data.tar.gz: 7d107fba6190bafa996da7cb9f081089d64d7d8bc1f1cbf2506e30b310e789b2567669b84208dc807456372e1330ebce5ac701b762f4d0c95b38551de18daf83
6
+ metadata.gz: b1ea6e403ab80bb108a90dff5f7ad58c39c228ed610ce497c631b5ae45a3ef5d2912100acd95ee33d7f2aa7c5609b71300c7a2322e1b2efcec688646573bf8da
7
+ data.tar.gz: d63d23350f0775bac73f28fdbabd0645798ed28a0466e7851ade38328a9f17e7a75982bc6bada6c1d951e4eb3ed0a4ffd872c79a6dc3c848f4308ddcfd11db16
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## 0.4.9
2
+
3
+ * Add client tests and stub with Webmock.
4
+
1
5
  ## 0.4.8
2
6
 
3
7
  * Feature: Allow more params with InteractiveReport.
data/README.md CHANGED
@@ -129,10 +129,48 @@ After checking out the repo, run `bin/setup` to install dependencies. Then, run
129
129
  `rake test` to run the tests. You can also run `bin/console` for an interactive
130
130
  prompt that will allow you to experiment.
131
131
 
132
- To install this gem onto your local machine, run `bundle exec rake install`. To
133
- release a new version, update the version number in `version.rb`, and then run
134
- `bundle exec rake release`, which will create a git tag for the version, push
135
- git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
132
+ To install this gem onto your local machine, run `bundle exec rake install`.
133
+
134
+ ### Release a new version
135
+
136
+ We're following semver for the release process of this gem. Make sure to apply the correct semver version for a new release.
137
+
138
+ To release a new version, run the `bin/release x.x.x`. That's it.
139
+
140
+ > **NOTE:** You don't have to add a v to the version you want to release. The release script will handle that for you.
141
+
142
+ ### Testing
143
+
144
+ For non-client tests, create the test class or case.
145
+
146
+ For client tests, you'll need to add a couple steps. If running against a real
147
+ backend, you'll need to provide a couple of environment variables:
148
+ `FULFIL_SUBDOMAIN` and `FULFIL_TOKEN`. Additionally, pass `debug: true` to the
149
+ client instance in the test. This will output the response body. Webmock will
150
+ probably complain that real requests aren't allowed at this point, offering you
151
+ the stub. We don't need most of that.
152
+
153
+ We will need to capture the response body as JSON and store it in the
154
+ `test/fixtures` directory. Formatted for readability, please. You'll also need
155
+ to make note of the path and body of the request. Once you have that, you can
156
+ generate your stub.
157
+
158
+ To stub a request, use (or create) the helper method based on the verb. For
159
+ example, to stub a `GET` request, use `stub_fulfil_get`. Here's an example:
160
+
161
+ ```ruby
162
+ def test_find_one
163
+ stub_fulfil_get('sale.sale/213112', 'sale_sale')
164
+
165
+ client = Fulfil::Client.new
166
+ response = client.find_one(model: 'sale.sale', id: 213_112)
167
+
168
+ assert_equal 213_112, response['id']
169
+ end
170
+ ```
171
+
172
+ `stub_fulfil_get` takes two arguments: the URL path (after `/api/v2/model/`)
173
+ and the fixture file name to be returned.
136
174
 
137
175
  ## Contributing
138
176
 
data/lib/fulfil/client.rb CHANGED
@@ -10,6 +10,12 @@ module Fulfil
10
10
  OAUTH_TOKEN = ENV['FULFIL_TOKEN']
11
11
 
12
12
  class Client
13
+ class InvalidClientError < StandardError
14
+ def message
15
+ 'Client is not configured correctly.'
16
+ end
17
+ end
18
+
13
19
  class NotAuthorizedError < StandardError; end
14
20
 
15
21
  class UnknownHTTPError < StandardError; end
@@ -24,6 +30,16 @@ module Fulfil
24
30
  @debug = debug
25
31
  @headers = headers
26
32
  @headers.delete('X-API-KEY') if @token
33
+
34
+ raise InvalidClientError if invalid?
35
+ end
36
+
37
+ def invalid?
38
+ @subdomain.nil? || @subdomain.empty?
39
+ end
40
+
41
+ def valid?
42
+ !invalid?
27
43
  end
28
44
 
29
45
  def find(model:, ids: [], id: nil, fields: %w[id rec_name])
@@ -125,19 +141,12 @@ module Fulfil
125
141
  end
126
142
 
127
143
  def request(endpoint:, verb: :get, **args)
144
+ raise InvalidClientError if invalid?
145
+
128
146
  response = client.request(verb, endpoint, args)
147
+ Fulfil::ResponseHandler.new(response).verify!
129
148
 
130
- if response.status.ok? || response.status.created?
131
- response.parse
132
- elsif response.code == 204
133
- []
134
- elsif response.code == 401
135
- error = response.parse
136
- raise NotAuthorizedError, "Not authorized: #{error['error']}: #{error['error_description']}"
137
- else
138
- puts response.body.to_s
139
- raise Error, 'Error encountered while processing response:'
140
- end
149
+ response.parse
141
150
  rescue HTTP::Error => e
142
151
  puts e
143
152
  raise UnknownHTTPError, 'Unhandled HTTP error encountered'
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Fulfil
4
+ class Error < StandardError; end
5
+
6
+ # The `Fulfil::HttpError` is raised whenever an API request returns a 400+ HTTP status code.
7
+ # See `Fulfil::ResponseHandler` for more information.
8
+ class HttpError < Error
9
+ attr_reader :metadata
10
+
11
+ def initialize(message, metadata = {})
12
+ @metadata = metadata
13
+ super(message)
14
+ end
15
+
16
+ class BadRequest < HttpError; end
17
+ class AuthorizationRequired < HttpError; end
18
+ class PaymentRequired < HttpError; end
19
+ class Forbidden < HttpError; end
20
+ class NotFound < HttpError; end
21
+ class MethodNotAllowed < HttpError; end
22
+ class NotAccepted < HttpError; end
23
+ class UnprocessableEntity < HttpError; end
24
+ class TooManyRequests < HttpError; end
25
+ class InternalServerError < HttpError; end
26
+ end
27
+ end
@@ -37,4 +37,4 @@ module Fulfil
37
37
  }
38
38
  end
39
39
  end
40
- end
40
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Fulfil
4
+ # The `Fulfil::ResponseHandler` is parses the HTTP response from Fulfil. If it
5
+ # encounters an HTTP status code that indicates an error, it will raise an internal
6
+ # exception that the consumer can catch.
7
+ #
8
+ # @example
9
+ # Fulfil::ResponseHandler.new(@response).verify!
10
+ # => true
11
+ #
12
+ # Fulfil::ResponseHandler.new(@response).verify!
13
+ # => Fulfil::Error::BadRequest
14
+ class ResponseHandler
15
+ HTTP_ERROR_CODES = {
16
+ 400 => Fulfil::HttpError::BadRequest,
17
+ 401 => Fulfil::HttpError::AuthorizationRequired,
18
+ 402 => Fulfil::HttpError::PaymentRequired,
19
+ 403 => Fulfil::HttpError::Forbidden,
20
+ 404 => Fulfil::HttpError::NotFound,
21
+ 405 => Fulfil::HttpError::MethodNotAllowed,
22
+ 406 => Fulfil::HttpError::NotAccepted,
23
+ 422 => Fulfil::HttpError::UnprocessableEntity,
24
+ 429 => Fulfil::HttpError::TooManyRequests,
25
+ 500 => Fulfil::HttpError::InternalServerError
26
+ }.freeze
27
+
28
+ def initialize(response)
29
+ @response = response
30
+ @status_code = response.code
31
+ end
32
+
33
+ def verify!
34
+ return true unless @status_code >= 400
35
+
36
+ raise HTTP_ERROR_CODES.fetch(@status_code, Fulfil::HttpError).new(
37
+ response_body['error_description'],
38
+ {
39
+ body: @response.body,
40
+ headers: @response.headers,
41
+ status: @response.status
42
+ }
43
+ )
44
+ end
45
+
46
+ private
47
+
48
+ def response_body
49
+ @response_body ||= @response.parse
50
+ end
51
+ end
52
+ end
@@ -41,7 +41,7 @@ module Fulfil
41
41
  def self.group(key_value_tuples)
42
42
  key_value_tuples
43
43
  .group_by { |kv_tuple| kv_tuple[0][0] }
44
- .map { |group_key, kv_tuples|
44
+ .map do |group_key, kv_tuples|
45
45
  if kv_tuples.length == 1
46
46
  [group_key, mapped_value_field(value: kv_tuples[0][1])]
47
47
  else
@@ -49,7 +49,7 @@ module Fulfil
49
49
  attrs = kv_tuples[1..-1].map { |tuple| [tuple[0][1..-1], tuple[1]] }
50
50
  [group_key, [['id', id[1]]].concat(group(attrs)).to_h]
51
51
  end
52
- }
52
+ end
53
53
  end
54
54
 
55
55
  def self.parse(item:)
@@ -57,5 +57,4 @@ module Fulfil
57
57
  group(key_value_tuples).to_h
58
58
  end
59
59
  end
60
-
61
60
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Fulfil
4
- VERSION = '0.4.8'
4
+ VERSION = "0.5.0"
5
5
  end
data/lib/fulfil.rb CHANGED
@@ -1,9 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'fulfil/version'
4
+ require 'fulfil/error'
2
5
  require 'fulfil/client'
3
6
  require 'fulfil/model'
4
7
  require 'fulfil/interactive_report'
8
+ require 'fulfil/response_handler'
5
9
  require 'fulfil/response_parser'
6
10
 
7
11
  module Fulfil
8
- class Error < StandardError; end
9
12
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fulfil-io
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.8
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Moore
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2021-11-30 00:00:00.000000000 Z
12
+ date: 2021-12-26 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: http
@@ -95,6 +95,20 @@ dependencies:
95
95
  - - ">="
96
96
  - !ruby/object:Gem::Version
97
97
  version: '0'
98
+ - !ruby/object:Gem::Dependency
99
+ name: webmock
100
+ requirement: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ type: :development
106
+ prerelease: false
107
+ version_requirements: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
98
112
  description:
99
113
  email:
100
114
  - chris@knowndecimal.com
@@ -111,9 +125,11 @@ files:
111
125
  - Rakefile
112
126
  - lib/fulfil.rb
113
127
  - lib/fulfil/client.rb
128
+ - lib/fulfil/error.rb
114
129
  - lib/fulfil/interactive_report.rb
115
130
  - lib/fulfil/model.rb
116
131
  - lib/fulfil/query.rb
132
+ - lib/fulfil/response_handler.rb
117
133
  - lib/fulfil/response_parser.rb
118
134
  - lib/fulfil/version.rb
119
135
  homepage: https://github.com/knowndecimal/fulfil