Skip to content

Commit 69670ba

Browse files
committed
Change TOKEN_URL to TOKEN_PATH and rescue JSON::ParserError
1 parent 339f301 commit 69670ba

File tree

3 files changed

+32
-19
lines changed

3 files changed

+32
-19
lines changed

lib/x/oauth2_authenticator.rb

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ module X
88
# Handles OAuth 2.0 authentication with token refresh capability
99
# @api public
1010
class OAuth2Authenticator < Authenticator
11-
# URL for the OAuth 2.0 token endpoint
12-
TOKEN_URL = "https://api.twitter.com/2/oauth2/token".freeze
11+
# Path for the OAuth 2.0 token endpoint
12+
TOKEN_PATH = "/2/oauth2/token".freeze
1313
# Host for token refresh requests
1414
TOKEN_HOST = "api.twitter.com".freeze
1515
# Port for token refresh requests
@@ -131,7 +131,7 @@ def build_http_client
131131
# @api private
132132
# @return [Net::HTTP::Post] the POST request
133133
def build_token_request
134-
request = Net::HTTP::Post.new(TOKEN_URL)
134+
request = Net::HTTP::Post.new(TOKEN_PATH)
135135
request["Content-Type"] = "application/x-www-form-urlencoded"
136136
request["Authorization"] = "Basic #{Base64.strict_encode64("#{client_id}:#{client_secret}")}"
137137
request.body = URI.encode_www_form(grant_type: REFRESH_GRANT_TYPE, refresh_token: refresh_token)
@@ -145,10 +145,11 @@ def build_token_request
145145
# @raise [Error] if the response indicates an error
146146
def handle_token_response(response)
147147
body = JSON.parse(response.body)
148-
unless response.is_a?(Net::HTTPSuccess)
149-
error_message = body["error_description"] || body["error"] || "Token refresh failed"
150-
raise Error, error_message
151-
end
148+
rescue JSON::ParserError
149+
raise Error, "Token refresh failed"
150+
else
151+
raise Error, body["error_description"] || body["error"] || "Token refresh failed" unless response.is_a?(Net::HTTPSuccess)
152+
152153
update_tokens(body)
153154
body
154155
end

sig/x.rbs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ module X
209209
end
210210

211211
class OAuth2Authenticator < Authenticator
212-
TOKEN_URL: String
212+
TOKEN_PATH: String
213213
TOKEN_HOST: String
214214
TOKEN_PORT: Integer
215215
REFRESH_GRANT_TYPE: String

test/x/oauth2_authenticator_test.rb

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
require_relative "../test_helper"
22

33
module X
4+
TOKEN_URL = "https://#{OAuth2Authenticator::TOKEN_HOST}#{OAuth2Authenticator::TOKEN_PATH}".freeze
5+
46
class OAuth2AuthenticatorInitializationTest < Minitest::Test
57
cover OAuth2Authenticator
68

@@ -75,7 +77,7 @@ class OAuth2AuthenticatorRefreshTokenTest < Minitest::Test
7577

7678
def test_refresh_token_sends_correct_content_type
7779
authenticator = OAuth2Authenticator.new(**test_oauth2_credentials)
78-
stub_request(:post, OAuth2Authenticator::TOKEN_URL)
80+
stub_request(:post, TOKEN_URL)
7981
.with(headers: {"Content-Type" => "application/x-www-form-urlencoded"})
8082
.to_return(status: 200, body: {access_token: "new"}.to_json)
8183

@@ -85,7 +87,7 @@ def test_refresh_token_sends_correct_content_type
8587
def test_refresh_token_sends_basic_auth_header
8688
authenticator = OAuth2Authenticator.new(**test_oauth2_credentials)
8789
expected_auth = "Basic #{Base64.strict_encode64("#{TEST_CLIENT_ID}:#{TEST_CLIENT_SECRET}")}"
88-
stub_request(:post, OAuth2Authenticator::TOKEN_URL)
90+
stub_request(:post, TOKEN_URL)
8991
.with(headers: {"Authorization" => expected_auth})
9092
.to_return(status: 200, body: {access_token: "new"}.to_json)
9193

@@ -95,7 +97,7 @@ def test_refresh_token_sends_basic_auth_header
9597
def test_refresh_token_sends_correct_request_body
9698
authenticator = OAuth2Authenticator.new(**test_oauth2_credentials)
9799
expected_body = "grant_type=refresh_token&refresh_token=#{TEST_REFRESH_TOKEN}"
98-
stub_request(:post, OAuth2Authenticator::TOKEN_URL)
100+
stub_request(:post, TOKEN_URL)
99101
.with(body: expected_body)
100102
.to_return(status: 200, body: {access_token: "new"}.to_json)
101103

@@ -104,7 +106,7 @@ def test_refresh_token_sends_correct_request_body
104106

105107
def test_refresh_token_updates_access_token
106108
authenticator = OAuth2Authenticator.new(**test_oauth2_credentials)
107-
stub_request(:post, OAuth2Authenticator::TOKEN_URL)
109+
stub_request(:post, TOKEN_URL)
108110
.to_return(status: 200, body: {access_token: "NEW_ACCESS_TOKEN"}.to_json)
109111

110112
authenticator.refresh_token!
@@ -114,7 +116,7 @@ def test_refresh_token_updates_access_token
114116

115117
def test_refresh_token_updates_refresh_token
116118
authenticator = OAuth2Authenticator.new(**test_oauth2_credentials)
117-
stub_request(:post, OAuth2Authenticator::TOKEN_URL)
119+
stub_request(:post, TOKEN_URL)
118120
.to_return(status: 200, body: {access_token: "new", refresh_token: "NEW_REFRESH"}.to_json)
119121

120122
authenticator.refresh_token!
@@ -124,7 +126,7 @@ def test_refresh_token_updates_refresh_token
124126

125127
def test_refresh_token_returns_response_body
126128
authenticator = OAuth2Authenticator.new(**test_oauth2_credentials)
127-
stub_request(:post, OAuth2Authenticator::TOKEN_URL)
129+
stub_request(:post, TOKEN_URL)
128130
.to_return(status: 200, body: {access_token: "new"}.to_json)
129131

130132
result = authenticator.refresh_token!
@@ -134,7 +136,7 @@ def test_refresh_token_returns_response_body
134136

135137
def test_refresh_token_updates_expires_at
136138
authenticator = OAuth2Authenticator.new(**test_oauth2_credentials)
137-
stub_request(:post, OAuth2Authenticator::TOKEN_URL)
139+
stub_request(:post, TOKEN_URL)
138140
.to_return(status: 200, body: {access_token: "new", expires_in: 7200}.to_json)
139141

140142
before_refresh = Time.now
@@ -145,7 +147,7 @@ def test_refresh_token_updates_expires_at
145147

146148
def test_refresh_token_keeps_old_refresh_token_when_not_returned
147149
authenticator = OAuth2Authenticator.new(**test_oauth2_credentials)
148-
stub_request(:post, OAuth2Authenticator::TOKEN_URL)
150+
stub_request(:post, TOKEN_URL)
149151
.to_return(status: 200, body: {access_token: "new"}.to_json)
150152

151153
authenticator.refresh_token!
@@ -160,7 +162,7 @@ class OAuth2AuthenticatorRefreshTokenErrorTest < Minitest::Test
160162
def test_refresh_token_raises_on_error_with_description
161163
authenticator = OAuth2Authenticator.new(**test_oauth2_credentials)
162164

163-
stub_request(:post, OAuth2Authenticator::TOKEN_URL)
165+
stub_request(:post, TOKEN_URL)
164166
.to_return(status: 400, body: {error: "invalid_grant", error_description: "Token expired"}.to_json)
165167

166168
error = assert_raises(Error) { authenticator.refresh_token! }
@@ -170,7 +172,7 @@ def test_refresh_token_raises_on_error_with_description
170172
def test_refresh_token_raises_on_error_without_description
171173
authenticator = OAuth2Authenticator.new(**test_oauth2_credentials)
172174

173-
stub_request(:post, OAuth2Authenticator::TOKEN_URL)
175+
stub_request(:post, TOKEN_URL)
174176
.to_return(status: 400, body: {error: "invalid_grant"}.to_json)
175177

176178
error = assert_raises(Error) { authenticator.refresh_token! }
@@ -180,11 +182,21 @@ def test_refresh_token_raises_on_error_without_description
180182
def test_refresh_token_raises_on_error_with_default_message
181183
authenticator = OAuth2Authenticator.new(**test_oauth2_credentials)
182184

183-
stub_request(:post, OAuth2Authenticator::TOKEN_URL)
185+
stub_request(:post, TOKEN_URL)
184186
.to_return(status: 500, body: {}.to_json)
185187

186188
error = assert_raises(Error) { authenticator.refresh_token! }
187189
assert_equal "Token refresh failed", error.message
188190
end
191+
192+
def test_refresh_token_raises_on_invalid_json_response
193+
authenticator = OAuth2Authenticator.new(**test_oauth2_credentials)
194+
195+
stub_request(:post, TOKEN_URL)
196+
.to_return(status: 500, body: "Internal Server Error")
197+
198+
error = assert_raises(Error) { authenticator.refresh_token! }
199+
assert_equal "Token refresh failed", error.message
200+
end
189201
end
190202
end

0 commit comments

Comments
 (0)