wotc 0.1.13 → 0.1.15

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
  SHA256:
3
- metadata.gz: 7b0635ac8c0081337f768aa467b607644558c050773cc5953ffcc0ce0e1090cd
4
- data.tar.gz: d8a2babb3e7ff987f011f9c303d59e174e30e93218b583ca8908e9ec759e0254
3
+ metadata.gz: 5e1dc3eee513b938983d7d4068e6886e885f46741067ed4b46ec2a39c3766f09
4
+ data.tar.gz: 17408d0f062dd9a0a771afcc763af24d031cc08d59f79ae30f827cd03333f3a5
5
5
  SHA512:
6
- metadata.gz: 4170f8d7b6a117d094edd7eafbc8b69f8c5ca64a4ad723a40ab4db5c67eed93df0ca14f0e8689693dd678ef16df86e998a10d81b8b3a3b08d3b27d0fde0a05e4
7
- data.tar.gz: b25ec62029a92c2248bbfac4da3d9571287b3aacaf991b472c2b972817d4455e131ea36465de88ab8d6c4609584e61eb2eef98ed8dcfb59b187aa0cdf3fcb4f7
6
+ metadata.gz: 6d448a43e5cc6bf75f4d54d9be6e4e8e6e44b45459a8155d1856efb93b26efaa1c68804040a7bdb811d0401b16ef60c8735a044d368e8f10de437cd5014f58e4
7
+ data.tar.gz: 4aff0246f7f5b6b5d8faca647238b0d86f0448ff71142b4844c448b63c50674d4aa79ce1d54ebc9e701198556dd7ddc7d955b59e9de6b2b16a9511f1d8b6f9a8
@@ -0,0 +1,18 @@
1
+ name: Test
2
+
3
+ on:
4
+ push:
5
+ branches: [master]
6
+ pull_request:
7
+
8
+ jobs:
9
+ rspec:
10
+ runs-on: ubuntu-latest
11
+ steps:
12
+ - uses: actions/checkout@v4
13
+ - uses: ruby/setup-ruby@v1
14
+ with:
15
+ # Matches the consuming backend's Ruby.
16
+ ruby-version: '3.0.4'
17
+ bundler-cache: true
18
+ - run: bundle exec rspec
data/.gitignore CHANGED
@@ -6,3 +6,4 @@
6
6
  /pkg/
7
7
  /spec/reports/
8
8
  /tmp/
9
+ Gemfile.lock
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 3.0.4
data/CHANGELOG.md CHANGED
@@ -0,0 +1,33 @@
1
+ # Changelog
2
+
3
+ ## 0.1.15 (unreleased)
4
+
5
+ - Every 4xx and 5xx from wotc.com now raises. Named statuses get their own
6
+ class (403 → `WOTC::Forbidden`, 422 → `WOTC::UnprocessableEntity`,
7
+ 429 → `WOTC::TooManyRequests`); anything unnamed raises `WOTC::ClientError`
8
+ or `WOTC::ServerError`. Previously a 403 — and any status without a `case`
9
+ arm — passed through as if the request had succeeded, which is how a 403
10
+ came to look like a revoked token (WS-50887). All new classes subclass
11
+ `WOTC::Error`, so existing rescues still catch them.
12
+ - New: `WOTC::Client#token_state` → `:valid` / `:revoked` / `:unknown`.
13
+ Only a 401 means `:revoked`; a 403, a 5xx, a timeout or an unreadable body
14
+ is `:unknown` and must not be treated as revocation. `token_valid?` is kept
15
+ for compatibility and now delegates to `token_state`, collapsing `:revoked`
16
+ and `:unknown` into the same `false`.
17
+ - `WOTC::MissingRequiredArgument` now subclasses `StandardError` and takes a
18
+ plain message; it previously inherited `Error#initialize(response)` and
19
+ crashed at the raise site.
20
+ - Auth header set via the `request :authorization` middleware instead of the
21
+ deprecated `Connection#authorization` (silences the per-request warning;
22
+ faraday `>= 1.8` now required). Dropped an unused `require 'base64'` that
23
+ triggered the Ruby 3.4 default-gem warning.
24
+
25
+ ## 0.1.14 (2026-03-16)
26
+
27
+ - Error middleware handles `Faraday::Response` correctly. Before this, every
28
+ raise from the middleware crashed with `NoMethodError` on `Faraday::Env`,
29
+ so no typed `WOTC::*` error had ever reached a caller.
30
+
31
+ ## 0.1.13 and earlier
32
+
33
+ - Untracked.
@@ -7,24 +7,33 @@ module FaradayMiddleWare
7
7
  end
8
8
 
9
9
  def call(env)
10
- @app.call(env).on_complete do |response|
11
- case response.status.to_i
12
- when 400
13
- raise WOTC::BadRequest.new(response)
14
- when 401
15
- raise WOTC::Unauthorized.new(response)
16
- when 404
17
- raise WOTC::NotFound.new(response)
18
- when 500
19
- raise WOTC::InternalServerError.new(response)
20
- when 502
21
- raise WOTC::BadGateway.new(response)
22
- when 503
23
- raise WOTC::ServiceUnavailable.new(response)
24
- when 504
25
- raise WOTC::GatewayTimeout.new(response)
26
- end
10
+ response = @app.call(env)
11
+ response.on_complete do |_env|
12
+ error = error_class(response.status.to_i)
13
+ raise error.new(response) if error
14
+ end
15
+ end
16
+
17
+ private
18
+
19
+ # Every 4xx and 5xx raises. The named statuses get their own class; anything
20
+ # else falls back to ClientError or ServerError, so a status we have not
21
+ # thought about can never be mistaken for a successful response.
22
+ def error_class(status)
23
+ case status
24
+ when 400 then WOTC::BadRequest
25
+ when 401 then WOTC::Unauthorized
26
+ when 403 then WOTC::Forbidden
27
+ when 404 then WOTC::NotFound
28
+ when 422 then WOTC::UnprocessableEntity
29
+ when 429 then WOTC::TooManyRequests
30
+ when 500 then WOTC::InternalServerError
31
+ when 502 then WOTC::BadGateway
32
+ when 503 then WOTC::ServiceUnavailable
33
+ when 504 then WOTC::GatewayTimeout
34
+ when 400..499 then WOTC::ClientError
35
+ when 500..599 then WOTC::ServerError
27
36
  end
28
37
  end
29
38
  end
30
- end
39
+ end
@@ -3,14 +3,30 @@ module WOTC
3
3
  # Defines methods related to utils
4
4
  module Utils
5
5
 
6
- # Trigger an api call to verify access_token is valid.
6
+ # Ask wotc.com whether our access token is still accepted.
7
+ #
8
+ # Returns :valid, :revoked or :unknown.
9
+ #
10
+ # Only a 401 means revoked. A 403, a 5xx, a timeout or a body we cannot
11
+ # read means we could not tell, and callers must not treat that as
12
+ # revocation.
13
+ def token_state
14
+ body = get('user').body
15
+ return :valid if body.is_a?(Hash) && !body['id'].nil?
16
+
17
+ :unknown
18
+ rescue WOTC::Unauthorized
19
+ :revoked
20
+ rescue StandardError
21
+ :unknown
22
+ end
23
+
24
+ # Kept for compatibility. Prefer #token_state: this collapses "revoked"
25
+ # and "could not tell" into the same false.
7
26
  def token_valid?
8
- user = get('user').body
9
- return true if user&.fetch("id")
10
- rescue => e
11
- return false
27
+ token_state == :valid
12
28
  end
13
-
29
+
14
30
  # Pre-qualify an application of WOTC status
15
31
  def wotc_calculator(options={})
16
32
  result = post('wotc/calculator', options)
@@ -18,4 +34,4 @@ module WOTC
18
34
  end
19
35
  end
20
36
  end
21
- end
37
+ end
@@ -17,7 +17,9 @@ module WOTC
17
17
  }.merge(connection_options)
18
18
 
19
19
  Faraday::Connection.new(options) do |conn|
20
- conn.authorization :Bearer, access_token
20
+ # Faraday 1.8+ middleware form; Connection#authorization is deprecated
21
+ # and removed in Faraday 2.0.
22
+ conn.request :authorization, :Bearer, access_token
21
23
  # https://github.com/lostisland/faraday/issues/417#issuecomment-223413386
22
24
  conn.options[:timeout] = timeout
23
25
  conn.options[:open_timeout] = open_timeout
data/lib/wotc/error.rb CHANGED
@@ -4,21 +4,27 @@ module WOTC
4
4
  attr_reader :http_method, :url, :errors
5
5
 
6
6
  def initialize(response)
7
- super
8
7
  @response = response.dup
9
- @http_method = response.env.method.to_s
10
- @url = response.env.url
11
- if response.body.is_a?(Hash) && !response.body.empty? && !response.body.fetch("errors", nil).nil?
12
- @raw_errors = response.body.fetch("errors")
8
+ env = response.env
9
+ # Use hash-style access for :method to avoid calling Kernel#method.
10
+ # Plain Ruby only: this gem does not depend on ActiveSupport.
11
+ http_method = env[:method].to_s.upcase
12
+ @http_method = http_method.empty? ? "UNKNOWN" : http_method
13
+ @url = env.url.to_s
14
+ @status = response.status
15
+ @body = response.body
16
+ if @body.is_a?(Hash) && !@body.empty? && !@body.fetch("errors", nil).nil?
17
+ @raw_errors = @body.fetch("errors")
13
18
  end
19
+ super()
14
20
  end
15
21
 
16
22
  def message
17
23
  <<-HEREDOC
18
24
  URL: #{@url}
19
25
  method: #{@http_method}
20
- response status: #{@response.status}
21
- response body: #{@response.body}
26
+ response status: #{@status}
27
+ response body: #{@body}
22
28
  HEREDOC
23
29
  end
24
30
 
@@ -38,27 +44,47 @@ module WOTC
38
44
  end
39
45
  end
40
46
 
47
+ # Any 4xx we do not name below. Our request was not accepted.
48
+ class ClientError < Error; end
49
+
50
+ # Any 5xx we do not name below. wotc.com could not answer. Retryable.
51
+ class ServerError < Error; end
52
+
41
53
  # Raised when wotc.com returns the HTTP status code 400
42
- class BadRequest < Error; end
54
+ class BadRequest < ClientError; end
55
+
56
+ # Raised when wotc.com returns the HTTP status code 401. This is the only
57
+ # status that means our access token was rejected.
58
+ class Unauthorized < ClientError; end
43
59
 
44
- # Raised when wotc.com returns the HTTP status code 401
45
- class Unauthorized < Error; end
60
+ # Raised when wotc.com returns the HTTP status code 403. Distinct from 401:
61
+ # the token authenticated, the action was refused, often because the resource
62
+ # does not exist or does not belong to this account.
63
+ class Forbidden < ClientError; end
46
64
 
47
65
  # Raised when wotc.com returns the HTTP status code 404
48
- class NotFound < Error; end
66
+ class NotFound < ClientError; end
67
+
68
+ # Raised when wotc.com returns the HTTP status code 422
69
+ class UnprocessableEntity < ClientError; end
70
+
71
+ # Raised when wotc.com returns the HTTP status code 429
72
+ class TooManyRequests < ClientError; end
49
73
 
50
74
  # Raised when wotc.com returns the HTTP status code 500
51
- class InternalServerError < Error; end
75
+ class InternalServerError < ServerError; end
52
76
 
53
77
  # Raised when wotc.com returns the HTTP status code 502
54
- class BadGateway < Error; end
78
+ class BadGateway < ServerError; end
55
79
 
56
80
  # Raised when wotc.com returns the HTTP status code 503
57
- class ServiceUnavailable < Error; end
81
+ class ServiceUnavailable < ServerError; end
58
82
 
59
83
  # Raised when wotc.com returns the HTTP status code 504
60
- class GatewayTimeout < Error; end
84
+ class GatewayTimeout < ServerError; end
61
85
 
62
- # Raised when client fails to provide required parameters.
63
- class MissingRequiredArgument < Error; end
86
+ # Raised when client code fails to provide required parameters — before any
87
+ # HTTP request exists. Unlike every class above it carries a plain message,
88
+ # not a Faraday::Response, so it cannot inherit Error#initialize.
89
+ class MissingRequiredArgument < StandardError; end
64
90
  end
data/lib/wotc/request.rb CHANGED
@@ -1,5 +1,3 @@
1
- require 'base64'
2
-
3
1
  module WOTC
4
2
  # Defines HTTP request methods
5
3
  module Request
data/lib/wotc/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module WOTC
2
- VERSION = '0.1.13'
2
+ VERSION = '0.1.15'
3
3
  end
data/wotc.gemspec CHANGED
@@ -40,7 +40,8 @@ Gem::Specification.new do |spec|
40
40
  spec.add_development_dependency "rspec", ">= 3.9.0"
41
41
  spec.add_development_dependency "pry"
42
42
  spec.add_development_dependency "webmock"
43
- spec.add_runtime_dependency 'faraday'
43
+ # >= 1.8 for the unified `request :authorization` middleware.
44
+ spec.add_runtime_dependency 'faraday', '>= 1.8'
44
45
  spec.add_runtime_dependency 'faraday_middleware'
45
46
  spec.add_runtime_dependency 'addressable'
46
47
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wotc
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.13
4
+ version: 0.1.15
5
5
  platform: ruby
6
6
  authors:
7
7
  - workstream.us
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-02-26 00:00:00.000000000 Z
11
+ date: 2026-07-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -86,14 +86,14 @@ dependencies:
86
86
  requirements:
87
87
  - - ">="
88
88
  - !ruby/object:Gem::Version
89
- version: '0'
89
+ version: '1.8'
90
90
  type: :runtime
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - ">="
95
95
  - !ruby/object:Gem::Version
96
- version: '0'
96
+ version: '1.8'
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: faraday_middleware
99
99
  requirement: !ruby/object:Gem::Requirement
@@ -129,8 +129,10 @@ executables: []
129
129
  extensions: []
130
130
  extra_rdoc_files: []
131
131
  files:
132
+ - ".github/workflows/test.yml"
132
133
  - ".gitignore"
133
134
  - ".rakeTasks"
135
+ - ".ruby-version"
134
136
  - ".travis.yml"
135
137
  - CHANGELOG.md
136
138
  - CODE_OF_CONDUCT.md
@@ -183,7 +185,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
183
185
  - !ruby/object:Gem::Version
184
186
  version: '0'
185
187
  requirements: []
186
- rubygems_version: 3.5.20
188
+ rubygems_version: 3.2.33
187
189
  signing_key:
188
190
  specification_version: 4
189
191
  summary: Ruby wrapper for wotc.com APIs