From 6390c69a0a658608740395cb017ab977664fb571 Mon Sep 17 00:00:00 2001 From: Erik Berlin Date: Wed, 27 Mar 2024 14:14:01 -0700 Subject: [PATCH] Updates for Ruby 3.2 --- .github/workflows/lint.yml | 2 +- .github/workflows/mutant.yml | 2 +- .github/workflows/steep.yml | 2 +- .github/workflows/test.yml | 2 +- .rubocop.yml | 2 +- examples/chunked_media_upload.rb | 4 ++-- examples/post_media_upload.rb | 2 +- lib/x/cgi.rb | 10 --------- lib/x/client.rb | 26 ++++++++++------------ lib/x/errors/too_many_requests.rb | 2 +- lib/x/media_uploader.rb | 19 ++++++++-------- lib/x/oauth_authenticator.rb | 6 ++--- lib/x/redirect_handler.rb | 4 ++-- lib/x/request_builder.rb | 6 ++--- lib/x/response_parser.rb | 4 ++-- sig/x.rbs | 4 ---- test/x/cgi_test.rb | 14 ------------ test/x/client_request_test.rb | 12 +++++----- test/x/connection_test.rb | 6 ++--- test/x/error_test.rb | 4 ++-- test/x/media_uploader_test.rb | 18 +++++++-------- test/x/rate_limit_test.rb | 2 +- test/x/redirect_handler_test.rb | 21 +++++++++--------- test/x/request_builder_test.rb | 2 +- test/x/response_parser_test.rb | 37 +++++++++++++++---------------- test/x/too_many_requests_test.rb | 4 ++-- x.gemspec | 2 +- 27 files changed, 92 insertions(+), 127 deletions(-) delete mode 100644 lib/x/cgi.rb delete mode 100644 test/x/cgi_test.rb diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 0e1902e..3d3a002 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -7,6 +7,6 @@ jobs: - uses: actions/checkout@v4 - uses: ruby/setup-ruby@v1 with: - ruby-version: "3.0" + ruby-version: "3.2" bundler-cache: true - run: bundle exec rake lint diff --git a/.github/workflows/mutant.yml b/.github/workflows/mutant.yml index 0b261d4..fe7e40e 100644 --- a/.github/workflows/mutant.yml +++ b/.github/workflows/mutant.yml @@ -7,6 +7,6 @@ jobs: - uses: actions/checkout@v4 - uses: ruby/setup-ruby@v1 with: - ruby-version: "3.0" + ruby-version: "3.2" bundler-cache: true - run: bundle exec rake mutant diff --git a/.github/workflows/steep.yml b/.github/workflows/steep.yml index a764897..ac8709c 100644 --- a/.github/workflows/steep.yml +++ b/.github/workflows/steep.yml @@ -7,6 +7,6 @@ jobs: - uses: actions/checkout@v4 - uses: ruby/setup-ruby@v1 with: - ruby-version: "3.0" + ruby-version: "3.2" bundler-cache: true - run: bundle exec rake steep diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index fa27728..9d1484c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -4,7 +4,7 @@ jobs: build: strategy: matrix: - ruby: ["3.0", "3.1", "3.2", "3.3"] + ruby: ["3.2", "3.3"] runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 diff --git a/.rubocop.yml b/.rubocop.yml index 976b554..6e931b0 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -7,7 +7,7 @@ require: AllCops: NewCops: enable - TargetRubyVersion: 3.0 + TargetRubyVersion: 3.2 Layout/ArgumentAlignment: EnforcedStyle: with_fixed_indentation diff --git a/examples/chunked_media_upload.rb b/examples/chunked_media_upload.rb index 5814496..64d63e5 100644 --- a/examples/chunked_media_upload.rb +++ b/examples/chunked_media_upload.rb @@ -12,9 +12,9 @@ file_path = "path/to/your/media.mp4" media_category = "tweet_video" # other options include: tweet_image, tweet_gif, dm_image, dm_video, dm_gif, subtitles -media = X::MediaUploader.chunked_upload(client: client, file_path: file_path, media_category: media_category) +media = X::MediaUploader.chunked_upload(client:, file_path:, media_category:) -X::MediaUploader.await_processing(client: client, media: media) +X::MediaUploader.await_processing(client:, media:) tweet_body = {text: "Posting media from @gem!", media: {media_ids: [media["media_id_string"]]}} diff --git a/examples/post_media_upload.rb b/examples/post_media_upload.rb index 7387585..74662e6 100644 --- a/examples/post_media_upload.rb +++ b/examples/post_media_upload.rb @@ -12,7 +12,7 @@ file_path = "path/to/your/media.jpg" media_category = "tweet_image" # other options are: dm_image or subtitles; for videos or GIFs use chunked_upload -media = X::MediaUploader.upload(client: client, file_path: file_path, media_category: media_category) +media = X::MediaUploader.upload(client:, file_path:, media_category:) tweet_body = {text: "Posting media from @gem!", media: {media_ids: [media["media_id_string"]]}} diff --git a/lib/x/cgi.rb b/lib/x/cgi.rb deleted file mode 100644 index 1e064bf..0000000 --- a/lib/x/cgi.rb +++ /dev/null @@ -1,10 +0,0 @@ -require "cgi" - -module X - class CGI - # TODO: Replace CGI.escape with CGI.escapeURIComponent when support for Ruby 3.1 is dropped - def self.escape(value) - ::CGI.escape(value).gsub("+", "%20") - end - end -end diff --git a/lib/x/client.rb b/lib/x/client.rb index 2221977..65e0c35 100644 --- a/lib/x/client.rb +++ b/lib/x/client.rb @@ -38,27 +38,26 @@ def initialize(api_key: nil, api_key_secret: nil, access_token: nil, access_toke initialize_authenticator @base_url = base_url initialize_default_classes(default_array_class, default_object_class) - @connection = Connection.new(open_timeout: open_timeout, read_timeout: read_timeout, write_timeout: write_timeout, - debug_output: debug_output, proxy_url: proxy_url) + @connection = Connection.new(open_timeout:, read_timeout:, write_timeout:, debug_output:, proxy_url:) @request_builder = RequestBuilder.new - @redirect_handler = RedirectHandler.new(connection: @connection, request_builder: @request_builder, max_redirects: max_redirects) + @redirect_handler = RedirectHandler.new(connection: @connection, request_builder: @request_builder, max_redirects:) @response_parser = ResponseParser.new end def get(endpoint, headers: {}, array_class: default_array_class, object_class: default_object_class) - execute_request(:get, endpoint, headers: headers, array_class: array_class, object_class: object_class) + execute_request(:get, endpoint, headers:, array_class:, object_class:) end def post(endpoint, body = nil, headers: {}, array_class: default_array_class, object_class: default_object_class) - execute_request(:post, endpoint, body: body, headers: headers, array_class: array_class, object_class: object_class) + execute_request(:post, endpoint, body:, headers:, array_class:, object_class:) end def put(endpoint, body = nil, headers: {}, array_class: default_array_class, object_class: default_object_class) - execute_request(:put, endpoint, body: body, headers: headers, array_class: array_class, object_class: object_class) + execute_request(:put, endpoint, body:, headers:, array_class:, object_class:) end def delete(endpoint, headers: {}, array_class: default_array_class, object_class: default_object_class) - execute_request(:delete, endpoint, headers: headers, array_class: array_class, object_class: object_class) + execute_request(:delete, endpoint, headers:, array_class:, object_class:) end def api_key=(api_key) @@ -103,10 +102,9 @@ def initialize_default_classes(default_array_class, default_object_class) def initialize_authenticator @authenticator = if api_key && api_key_secret && access_token && access_token_secret - OAuthAuthenticator.new(api_key: api_key, api_key_secret: api_key_secret, access_token: access_token, - access_token_secret: access_token_secret) + OAuthAuthenticator.new(api_key:, api_key_secret:, access_token:, access_token_secret:) elsif bearer_token - BearerTokenAuthenticator.new(bearer_token: bearer_token) + BearerTokenAuthenticator.new(bearer_token:) elsif @authenticator.nil? Authenticator.new else @@ -116,10 +114,10 @@ def initialize_authenticator def execute_request(http_method, endpoint, body: nil, headers: {}, array_class: default_array_class, object_class: default_object_class) uri = URI.join(base_url, endpoint) - request = @request_builder.build(http_method: http_method, uri: uri, body: body, headers: headers, authenticator: @authenticator) - response = @connection.perform(request: request) - response = @redirect_handler.handle(response: response, request: request, base_url: base_url, authenticator: @authenticator) - @response_parser.parse(response: response, array_class: array_class, object_class: object_class) + request = @request_builder.build(http_method:, uri:, body:, headers:, authenticator: @authenticator) + response = @connection.perform(request:) + response = @redirect_handler.handle(response:, request:, base_url:, authenticator: @authenticator) + @response_parser.parse(response:, array_class:, object_class:) end end end diff --git a/lib/x/errors/too_many_requests.rb b/lib/x/errors/too_many_requests.rb index f91efea..afd3a71 100644 --- a/lib/x/errors/too_many_requests.rb +++ b/lib/x/errors/too_many_requests.rb @@ -9,7 +9,7 @@ def rate_limit def rate_limits @rate_limits ||= RateLimit::TYPES.filter_map do |type| - RateLimit.new(type: type, response: response) if response["x-#{type}-remaining"].eql?("0") + RateLimit.new(type:, response:) if response["x-#{type}-remaining"].eql?("0") end end diff --git a/lib/x/media_uploader.rb b/lib/x/media_uploader.rb index 4d5fca8..f6c6bc9 100644 --- a/lib/x/media_uploader.rb +++ b/lib/x/media_uploader.rb @@ -18,21 +18,20 @@ module MediaUploader def upload(client:, file_path:, media_category:, media_type: infer_media_type(file_path, media_category), boundary: SecureRandom.hex) - validate!(file_path: file_path, media_category: media_category) + validate!(file_path:, media_category:) upload_client = client.dup.tap { |c| c.base_url = "https://upload.twitter.com/1.1/" } - upload_body = construct_upload_body(file_path: file_path, media_type: media_type, boundary: boundary) + upload_body = construct_upload_body(file_path:, media_type:, boundary:) headers = {"Content-Type" => "multipart/form-data, boundary=#{boundary}"} - upload_client.post("media/upload.json?media_category=#{media_category}", upload_body, headers: headers) + upload_client.post("media/upload.json?media_category=#{media_category}", upload_body, headers:) end def chunked_upload(client:, file_path:, media_category:, media_type: infer_media_type(file_path, media_category), boundary: SecureRandom.hex, chunk_size_mb: 8) - validate!(file_path: file_path, media_category: media_category) + validate!(file_path:, media_category:) upload_client = client.dup.tap { |c| c.base_url = "https://upload.twitter.com/1.1/" } - media = init(upload_client: upload_client, file_path: file_path, media_type: media_type, media_category: media_category) + media = init(upload_client:, file_path:, media_type:, media_category:) chunk_size = chunk_size_mb * BYTES_PER_MB - append(upload_client: upload_client, file_paths: split(file_path, chunk_size), media: media, media_type: media_type, - boundary: boundary) + append(upload_client:, file_paths: split(file_path, chunk_size), media:, media_type:, boundary:) upload_client.post("media/upload.json?command=FINALIZE&media_id=#{media["media_id"]}") end @@ -88,17 +87,17 @@ def init(upload_client:, file_path:, media_type:, media_category:) def append(upload_client:, file_paths:, media:, media_type:, boundary: SecureRandom.hex) threads = file_paths.map.with_index do |file_path, index| Thread.new do - upload_body = construct_upload_body(file_path: file_path, media_type: media_type, boundary: boundary) + upload_body = construct_upload_body(file_path:, media_type:, boundary:) query = "command=APPEND&media_id=#{media["media_id"]}&segment_index=#{index}" headers = {"Content-Type" => "multipart/form-data, boundary=#{boundary}"} - upload_chunk(upload_client: upload_client, query: query, upload_body: upload_body, file_path: file_path, headers: headers) + upload_chunk(upload_client:, query:, upload_body:, file_path:, headers:) end end threads.each(&:join) end def upload_chunk(upload_client:, query:, upload_body:, file_path:, headers: {}) - upload_client.post("media/upload.json?#{query}", upload_body, headers: headers) + upload_client.post("media/upload.json?#{query}", upload_body, headers:) rescue NetworkError, ServerError retries ||= 0 ((retries += 1) < MAX_RETRIES) ? retry : raise diff --git a/lib/x/oauth_authenticator.rb b/lib/x/oauth_authenticator.rb index 9ec96c5..d0a0512 100644 --- a/lib/x/oauth_authenticator.rb +++ b/lib/x/oauth_authenticator.rb @@ -1,10 +1,10 @@ require "base64" +require "cgi" require "json" require "openssl" require "securerandom" require "uri" require_relative "authenticator" -require_relative "cgi" module X class OAuthAuthenticator < Authenticator @@ -71,7 +71,7 @@ def hmac_signature(base_string) end def signature_base_string(method, url, params) - "#{method}&#{CGI.escape(url)}&#{CGI.escape(URI.encode_www_form(params.sort))}" + "#{method}&#{CGI.escapeURIComponent(url)}&#{CGI.escapeURIComponent(URI.encode_www_form(params.sort))}" end def signing_key @@ -79,7 +79,7 @@ def signing_key end def format_oauth_header(params) - "OAuth #{params.sort.map { |k, v| "#{k}=\"#{CGI.escape(v)}\"" }.join(", ")}" + "OAuth #{params.sort.map { |k, v| "#{k}=\"#{CGI.escapeURIComponent(v)}\"" }.join(", ")}" end end end diff --git a/lib/x/redirect_handler.rb b/lib/x/redirect_handler.rb index 7c4346b..bda63dd 100644 --- a/lib/x/redirect_handler.rb +++ b/lib/x/redirect_handler.rb @@ -28,7 +28,7 @@ def handle(response:, request:, base_url:, authenticator: Authenticator.new, red new_request = build_request(request, new_uri, Integer(response.code), authenticator) new_response = connection.perform(request: new_request) - handle(response: new_response, request: new_request, base_url: base_url, redirect_count: redirect_count + 1) + handle(response: new_response, request: new_request, base_url:, redirect_count: redirect_count + 1) else response end @@ -50,7 +50,7 @@ def build_request(request, uri, response_code, authenticator) [:get, nil] end - request_builder.build(http_method: http_method, uri: uri, body: body, authenticator: authenticator) + request_builder.build(http_method:, uri:, body:, authenticator:) end end end diff --git a/lib/x/request_builder.rb b/lib/x/request_builder.rb index 31d8e5e..35d5fbf 100644 --- a/lib/x/request_builder.rb +++ b/lib/x/request_builder.rb @@ -17,9 +17,9 @@ class RequestBuilder }.freeze def build(http_method:, uri:, body: nil, headers: {}, authenticator: Authenticator.new) - request = create_request(http_method: http_method, uri: uri, body: body) - add_headers(request: request, headers: headers) - add_authentication(request: request, authenticator: authenticator) + request = create_request(http_method:, uri:, body:) + add_headers(request:, headers:) + add_authentication(request:, authenticator:) request end diff --git a/lib/x/response_parser.rb b/lib/x/response_parser.rb index 3828334..d24a4a1 100644 --- a/lib/x/response_parser.rb +++ b/lib/x/response_parser.rb @@ -41,13 +41,13 @@ def parse(response:, array_class: nil, object_class: nil) return unless json?(response) - JSON.parse(response.body, array_class: array_class, object_class: object_class) + JSON.parse(response.body, array_class:, object_class:) end private def error(response) - error_class(response).new(response: response) + error_class(response).new(response:) end def error_class(response) diff --git a/sig/x.rbs b/sig/x.rbs index fc56e62..dd38de8 100644 --- a/sig/x.rbs +++ b/sig/x.rbs @@ -281,8 +281,4 @@ module X def finalize: (upload_client: Client, media: untyped) -> untyped def construct_upload_body: (file_path: String, media_type: String, ?boundary: String) -> String end - - class CGI - def self.escape: (String value) -> String - end end diff --git a/test/x/cgi_test.rb b/test/x/cgi_test.rb deleted file mode 100644 index a76ca5c..0000000 --- a/test/x/cgi_test.rb +++ /dev/null @@ -1,14 +0,0 @@ -require_relative "../test_helper" - -module X - class CGITest < Minitest::Test - cover CGI - - def test_escape - assert_equal "escape%20two%20spaces", X::CGI.escape("escape two spaces") - assert_equal "foo%2Fbar", X::CGI.escape("foo/bar") - assert_equal "foo%2Bbar", X::CGI.escape("foo+bar") - assert_equal "%21%40%23%24", X::CGI.escape('!@#$') - end - end -end diff --git a/test/x/client_request_test.rb b/test/x/client_request_test.rb index af85ab6..b4136ee 100644 --- a/test/x/client_request_test.rb +++ b/test/x/client_request_test.rb @@ -19,9 +19,9 @@ def setup define_method :"test_#{http_method}_request_with_headers" do headers = {"User-Agent" => "Custom User Agent"} stub_request(http_method, "https://api.twitter.com/2/tweets") - @client.public_send(http_method, "tweets", headers: headers) + @client.public_send(http_method, "tweets", headers:) - assert_requested http_method, "https://api.twitter.com/2/tweets", headers: headers + assert_requested http_method, "https://api.twitter.com/2/tweets", headers: end define_method :"test_#{http_method}_request_with_custom_response_objects" do @@ -89,10 +89,10 @@ def test_follows_307_redirect .to_return(status: 307, headers: {"Location" => "https://api.twitter.com/new_endpoint"}) body = {key: "value"}.to_json stub_request(:post, "https://api.twitter.com/new_endpoint") - .with(body: body) + .with(body:) @client.post("/temporary_redirect", body) - assert_requested :post, "https://api.twitter.com/new_endpoint", body: body + assert_requested :post, "https://api.twitter.com/new_endpoint", body: end def test_follows_308_redirect @@ -100,10 +100,10 @@ def test_follows_308_redirect .to_return(status: 308, headers: {"Location" => "https://api.twitter.com/new_endpoint"}) body = {key: "value"}.to_json stub_request(:put, "https://api.twitter.com/new_endpoint") - .with(body: body) + .with(body:) @client.put("/temporary_redirect", body) - assert_requested :put, "https://api.twitter.com/new_endpoint", body: body + assert_requested :put, "https://api.twitter.com/new_endpoint", body: end def test_avoids_infinite_redirect_loop diff --git a/test/x/connection_test.rb b/test/x/connection_test.rb index 4d39b67..ac3f0b9 100644 --- a/test/x/connection_test.rb +++ b/test/x/connection_test.rb @@ -109,7 +109,7 @@ def test_set_env_proxy def test_perform stub_request(:get, "http://example.com:80") request = Net::HTTP::Get.new(URI("http://example.com:80")) - @connection.perform(request: request) + @connection.perform(request:) assert_requested :get, "http://example.com:80" end @@ -117,7 +117,7 @@ def test_perform def test_network_error stub_request(:get, "https://example.com").to_raise(Errno::ECONNREFUSED) request = Net::HTTP::Get.new(URI("https://example.com")) - error = assert_raises(NetworkError) { @connection.perform(request: request) } + error = assert_raises(NetworkError) { @connection.perform(request:) } assert_equal "Network error: Connection refused - Exception from WebMock", error.message end @@ -125,7 +125,7 @@ def test_network_error def test_no_host_or_port stub_request(:get, "http://api.twitter.com:443/2/tweets") request = Net::HTTP::Get.new(URI("http://api.twitter.com:443/2/tweets")) - request.stub(:uri, URI("/2/tweets")) { @connection.perform(request: request) } + request.stub(:uri, URI("/2/tweets")) { @connection.perform(request:) } assert_requested :get, "http://api.twitter.com:443/2/tweets" end diff --git a/test/x/error_test.rb b/test/x/error_test.rb index b350e17..66fc8d7 100644 --- a/test/x/error_test.rb +++ b/test/x/error_test.rb @@ -12,7 +12,7 @@ def setup name = error_class.name.split("::").last define_method :"test_initialize_#{name.downcase}_error" do response = Net::HTTPResponse::CODE_TO_OBJ[status.to_s].new("1.1", status, error_class.name) - exception = error_class.new(response: response) + exception = error_class.new(response:) assert_equal error_class.name, exception.message assert_equal response, exception.response @@ -41,7 +41,7 @@ def test_unexpected_response def test_problem_json body = {error: "problem"}.to_json stub_request(:get, "https://api.twitter.com/2/tweets") - .to_return(status: 400, headers: {"content-type" => "application/problem+json"}, body: body) + .to_return(status: 400, headers: {"content-type" => "application/problem+json"}, body:) begin @client.get("tweets") diff --git a/test/x/media_uploader_test.rb b/test/x/media_uploader_test.rb index 8624be2..267ee64 100644 --- a/test/x/media_uploader_test.rb +++ b/test/x/media_uploader_test.rb @@ -16,7 +16,7 @@ def test_upload stub_request(:post, "https://upload.twitter.com/1.1/media/upload.json?media_category=#{MediaUploader::TWEET_IMAGE}") .to_return(body: @media.to_json, headers: {"Content-Type" => "application/json"}) - result = MediaUploader.upload(client: @client, file_path: file_path, media_category: MediaUploader::TWEET_IMAGE, boundary: "AaB03x") + result = MediaUploader.upload(client: @client, file_path:, media_category: MediaUploader::TWEET_IMAGE, boundary: "AaB03x") assert_equal TEST_MEDIA_ID, result["media_id"] end @@ -24,14 +24,14 @@ def test_upload def test_chunked_upload file_path = "test/sample_files/sample.mp4" total_bytes = File.size(file_path) + chunk_size_mb = (total_bytes - 1) / MediaUploader::BYTES_PER_MB.to_f stub_request(:post, "https://upload.twitter.com/1.1/media/upload.json?command=INIT&media_category=tweet_video&media_type=video/mp4&total_bytes=#{total_bytes}") .to_return(status: 202, headers: {"content-type" => "application/json"}, body: @media.to_json) 2.times { |segment_index| stub_request(:post, "https://upload.twitter.com/1.1/media/upload.json?command=APPEND&media_id=#{TEST_MEDIA_ID}&segment_index=#{segment_index}").to_return(status: 204) } stub_request(:post, "https://upload.twitter.com/1.1/media/upload.json?command=FINALIZE&media_id=#{TEST_MEDIA_ID}") .to_return(status: 201, headers: {"content-type" => "application/json"}, body: @media.to_json) - response = MediaUploader.chunked_upload(client: @client, file_path: file_path, media_category: MediaUploader::TWEET_VIDEO, - chunk_size_mb: (total_bytes - 1) / MediaUploader::BYTES_PER_MB.to_f) + response = MediaUploader.chunked_upload(client: @client, file_path:, media_category: MediaUploader::TWEET_VIDEO, chunk_size_mb:) assert_equal TEST_MEDIA_ID, response["media_id"] end @@ -44,8 +44,7 @@ def test_append_method stub_request(:post, "https://upload.twitter.com/1.1/media/upload.json?command=APPEND&media_id=#{TEST_MEDIA_ID}&segment_index=#{segment_index}") .with(headers: {"Content-Type" => "multipart/form-data, boundary=AaB03x"}).to_return(status: 204) end - MediaUploader.send(:append, upload_client: @upload_client, file_paths: file_paths, media: @media, - media_type: "video/mp4", boundary: "AaB03x") + MediaUploader.send(:append, upload_client: @upload_client, file_paths:, media: @media, media_type: "video/mp4", boundary: "AaB03x") file_paths.each_with_index { |_, segment_index| assert_requested(:post, "https://upload.twitter.com/1.1/media/upload.json?command=APPEND&media_id=#{TEST_MEDIA_ID}&segment_index=#{segment_index}") } end @@ -77,27 +76,26 @@ def test_retry stub_request(:post, "https://upload.twitter.com/1.1/media/upload.json?command=FINALIZE&media_id=#{TEST_MEDIA_ID}") .to_return(status: 201, headers: {"content-type" => "application/json"}, body: @media.to_json) - assert MediaUploader.chunked_upload(client: @client, file_path: file_path, - media_category: MediaUploader::TWEET_VIDEO) + assert MediaUploader.chunked_upload(client: @client, file_path:, media_category: MediaUploader::TWEET_VIDEO) end def test_validate_with_valid_params file_path = "test/sample_files/sample.jpg" - assert_nil MediaUploader.send(:validate!, file_path: file_path, media_category: MediaUploader::TWEET_IMAGE) + assert_nil MediaUploader.send(:validate!, file_path:, media_category: MediaUploader::TWEET_IMAGE) end def test_validate_with_invalid_file_path file_path = "invalid/file/path" assert_raises(RuntimeError) do - MediaUploader.send(:validate!, file_path: file_path, media_category: MediaUploader::TWEET_IMAGE) + MediaUploader.send(:validate!, file_path:, media_category: MediaUploader::TWEET_IMAGE) end end def test_validate_with_invalid_media_category file_path = "test/sample_files/sample.jpg" assert_raises(ArgumentError) do - MediaUploader.send(:validate!, file_path: file_path, media_category: "invalid_category") + MediaUploader.send(:validate!, file_path:, media_category: "invalid_category") end end diff --git a/test/x/rate_limit_test.rb b/test/x/rate_limit_test.rb index 5188ecb..b6b1b6b 100644 --- a/test/x/rate_limit_test.rb +++ b/test/x/rate_limit_test.rb @@ -11,7 +11,7 @@ def setup "x-rate-limit-remaining" => "0", "x-rate-limit-reset" => (Time.now.to_i + 60).to_s } - @rate_limit = RateLimit.new(type: "rate-limit", response: response) + @rate_limit = RateLimit.new(type: "rate-limit", response:) end end diff --git a/test/x/redirect_handler_test.rb b/test/x/redirect_handler_test.rb index d128880..2123cb5 100644 --- a/test/x/redirect_handler_test.rb +++ b/test/x/redirect_handler_test.rb @@ -22,7 +22,7 @@ def test_handle_with_no_redirects response = Net::HTTPSuccess.new("1.1", "200", "OK") - assert_equal(response, @redirect_handler.handle(response: response, request: request, base_url: "http://example.com")) + assert_equal(response, @redirect_handler.handle(response:, request:, base_url: "http://example.com")) end def test_handle_with_one_redirect @@ -33,8 +33,7 @@ def test_handle_with_one_redirect response = Net::HTTPFound.new("1.1", "302", "Found") response["Location"] = "http://www.example.com" - @redirect_handler.handle(response: response, request: request, base_url: "http://example.com", - authenticator: authenticator) + @redirect_handler.handle(response:, request:, base_url: "http://example.com", authenticator:) assert_requested :get, "http://www.example.com" end @@ -47,7 +46,7 @@ def test_handle_with_two_redirects response = Net::HTTPFound.new("1.1", "307", "Found") response["Location"] = "http://example.com/2" - @redirect_handler.handle(response: response, request: request, base_url: "http://example.com") + @redirect_handler.handle(response:, request:, base_url: "http://example.com") assert_requested :delete, "http://example.com/2" assert_requested :delete, "http://example.com/3" @@ -60,7 +59,7 @@ def test_handle_with_relative_url response = Net::HTTPFound.new("1.1", "302", "Found") response["Location"] = "/some_relative_path" - @redirect_handler.handle(response: response, request: request, base_url: "http://example.com") + @redirect_handler.handle(response:, request:, base_url: "http://example.com") assert_requested :get, "http://example.com/some_relative_path" end @@ -72,7 +71,7 @@ def test_handle_with_301_moved_permanently response = Net::HTTPMovedPermanently.new("1.1", "301", "Moved Permanently") response["Location"] = "http://example.com/new_path" - @redirect_handler.handle(response: response, request: request, base_url: "http://example.com") + @redirect_handler.handle(response:, request:, base_url: "http://example.com") assert_requested :get, "http://example.com/new_path" end @@ -84,7 +83,7 @@ def test_handle_with_302_found response = Net::HTTPFound.new("1.1", "302", "Found") response["Location"] = "http://example.com/temp_path" - @redirect_handler.handle(response: response, request: request, base_url: "http://example.com") + @redirect_handler.handle(response:, request:, base_url: "http://example.com") assert_requested :get, "http://example.com/temp_path" end @@ -97,7 +96,7 @@ def test_handle_with_303_see_other response = Net::HTTPSeeOther.new("1.1", "303", "See Other") response["Location"] = "http://example.com/other_path" - @redirect_handler.handle(response: response, request: request, base_url: "http://example.com") + @redirect_handler.handle(response:, request:, base_url: "http://example.com") assert_requested :get, "http://example.com/other_path" end @@ -110,7 +109,7 @@ def test_handle_with_307_temporary_redirect response = Net::HTTPTemporaryRedirect.new("1.1", "307", "Temporary Redirect") response["Location"] = "http://example.com/temp_path" - @redirect_handler.handle(response: response, request: request, base_url: "http://example.com") + @redirect_handler.handle(response:, request:, base_url: "http://example.com") assert_requested :post, "http://example.com/temp_path", body: "request_body" end @@ -123,7 +122,7 @@ def test_handle_with_308_permanent_redirect response = Net::HTTPPermanentRedirect.new("1.1", "308", "Permanent Redirect") response["Location"] = "http://example.com/new_path" - @redirect_handler.handle(response: response, request: request, base_url: "http://example.com") + @redirect_handler.handle(response:, request:, base_url: "http://example.com") assert_requested :post, "http://example.com/new_path", body: "request_body" end @@ -136,7 +135,7 @@ def test_handle_with_too_many_redirects response["Location"] = "http://example.com/some_path" e = assert_raises(TooManyRedirects) do - @redirect_handler.handle(response: response, request: request, base_url: "http://example.com") + @redirect_handler.handle(response:, request:, base_url: "http://example.com") end assert_equal "Too many redirects", e.message diff --git a/test/x/request_builder_test.rb b/test/x/request_builder_test.rb index 9384d71..fbc4443 100644 --- a/test/x/request_builder_test.rb +++ b/test/x/request_builder_test.rb @@ -64,7 +64,7 @@ def test_unsupported_http_method def test_escape_query_params uri = "https://upload.twitter.com/1.1/media/upload.json?media_type=video/mp4" - request = @request_builder.build(http_method: :post, uri: uri, authenticator: @authenticator) + request = @request_builder.build(http_method: :post, uri:, authenticator: @authenticator) assert_equal "media_type=video%2Fmp4", request.uri.query end diff --git a/test/x/response_parser_test.rb b/test/x/response_parser_test.rb index 3d19df9..2a97579 100644 --- a/test/x/response_parser_test.rb +++ b/test/x/response_parser_test.rb @@ -18,25 +18,25 @@ def test_success_response stub_request(:get, @uri.to_s) .to_return(body: '{"message": "success"}', headers: {"Content-Type" => "application/json"}) - assert_equal({"message" => "success"}, @response_parser.parse(response: response)) + assert_equal({"message" => "success"}, @response_parser.parse(response:)) end def test_non_json_success_response stub_request(:get, @uri.to_s) .to_return(body: "", headers: {"Content-Type" => "text/html"}) - assert_nil @response_parser.parse(response: response) + assert_nil @response_parser.parse(response:) end def test_that_it_parses_204_no_content_response stub_request(:get, @uri.to_s).to_return(status: 204) - assert_nil @response_parser.parse(response: response) + assert_nil @response_parser.parse(response:) end def test_bad_request_error stub_request(:get, @uri.to_s).to_return(status: 400) - exception = assert_raises(BadRequest) { @response_parser.parse(response: response) } + exception = assert_raises(BadRequest) { @response_parser.parse(response:) } assert_kind_of Net::HTTPBadRequest, exception.response assert_equal "400", exception.code @@ -44,13 +44,13 @@ def test_bad_request_error def test_unknown_error_code stub_request(:get, @uri.to_s).to_return(status: 418) - assert_raises(Error) { @response_parser.parse(response: response) } + assert_raises(Error) { @response_parser.parse(response:) } end def test_too_many_requests_with_headers stub_request(:get, @uri.to_s) .to_return(status: 429, headers: {"x-rate-limit-remaining" => "0"}) - exception = assert_raises(TooManyRequests) { @response_parser.parse(response: response) } + exception = assert_raises(TooManyRequests) { @response_parser.parse(response:) } assert_predicate exception.rate_limits.first.remaining, :zero? end @@ -58,16 +58,16 @@ def test_too_many_requests_with_headers def test_error_with_title_only stub_request(:get, @uri.to_s) .to_return(status: [400, "Bad Request"], body: '{"title": "Some Error"}', headers: {"Content-Type" => "application/json"}) - exception = assert_raises(BadRequest) { @response_parser.parse(response: response) } + exception = assert_raises(BadRequest) { @response_parser.parse(response:) } assert_equal "Bad Request", exception.message end def test_error_with_detail_only stub_request(:get, @uri.to_s) - .to_return(status: [400, "Bad Request"], body: '{"detail": "Something went wrong"}', - headers: {"Content-Type" => "application/json"}) - exception = assert_raises(BadRequest) { @response_parser.parse(response: response) } + .to_return(status: [400, "Bad Request"], + body: '{"detail": "Something went wrong"}', headers: {"Content-Type" => "application/json"}) + exception = assert_raises(BadRequest) { @response_parser.parse(response:) } assert_equal "Bad Request", exception.message end @@ -76,7 +76,7 @@ def test_error_with_title_and_detail_error_message stub_request(:get, @uri.to_s) .to_return(status: 400, body: '{"title": "Some Error", "detail": "Something went wrong"}', headers: {"Content-Type" => "application/json"}) - exception = assert_raises(BadRequest) { @response_parser.parse(response: response) } + exception = assert_raises(BadRequest) { @response_parser.parse(response:) } assert_equal("Some Error: Something went wrong", exception.message) end @@ -84,7 +84,7 @@ def test_error_with_title_and_detail_error_message def test_error_with_error_message stub_request(:get, @uri.to_s) .to_return(status: 400, body: '{"error": "Some Error"}', headers: {"Content-Type" => "application/json"}) - exception = assert_raises(BadRequest) { @response_parser.parse(response: response) } + exception = assert_raises(BadRequest) { @response_parser.parse(response:) } assert_equal("Some Error", exception.message) end @@ -93,16 +93,15 @@ def test_error_with_errors_array_message stub_request(:get, @uri.to_s) .to_return(status: 400, body: '{"errors": [{"message": "Some Error"}, {"message": "Another Error"}]}', headers: {"Content-Type" => "application/json"}) - exception = assert_raises(BadRequest) { @response_parser.parse(response: response) } + exception = assert_raises(BadRequest) { @response_parser.parse(response:) } assert_equal("Some Error, Another Error", exception.message) end def test_error_with_errors_message stub_request(:get, @uri.to_s) - .to_return(status: 400, - body: '{"errors": {"message": "Some Error"}}', headers: {"Content-Type" => "application/json"}) - exception = assert_raises(BadRequest) { @response_parser.parse(response: response) } + .to_return(status: 400, body: '{"errors": {"message": "Some Error"}}', headers: {"Content-Type" => "application/json"}) + exception = assert_raises(BadRequest) { @response_parser.parse(response:) } assert_empty exception.message end @@ -110,7 +109,7 @@ def test_error_with_errors_message def test_non_json_error_response stub_request(:get, @uri.to_s) .to_return(status: [400, "Bad Request"], body: "Bad Request", headers: {"Content-Type" => "text/html"}) - exception = assert_raises(BadRequest) { @response_parser.parse(response: response) } + exception = assert_raises(BadRequest) { @response_parser.parse(response:) } assert_equal "Bad Request", exception.message end @@ -118,7 +117,7 @@ def test_non_json_error_response def test_default_response_objects stub_request(:get, @uri.to_s) .to_return(body: '{"array": [1, 2, 2, 3]}', headers: {"Content-Type" => "application/json"}) - hash = @response_parser.parse(response: response) + hash = @response_parser.parse(response:) assert_kind_of Hash, hash assert_kind_of Array, hash["array"] @@ -128,7 +127,7 @@ def test_default_response_objects def test_custom_response_objects stub_request(:get, @uri.to_s) .to_return(body: '{"set": [1, 2, 2, 3]}', headers: {"Content-Type" => "application/json"}) - ostruct = @response_parser.parse(response: response, object_class: OpenStruct, array_class: Set) + ostruct = @response_parser.parse(response:, object_class: OpenStruct, array_class: Set) assert_kind_of OpenStruct, ostruct assert_kind_of Set, ostruct.set diff --git a/test/x/too_many_requests_test.rb b/test/x/too_many_requests_test.rb index 6e3cd35..4d4e451 100644 --- a/test/x/too_many_requests_test.rb +++ b/test/x/too_many_requests_test.rb @@ -11,13 +11,13 @@ def setup response["x-rate-limit-remaining"] = "0" response["x-rate-limit-reset"] = (Time.now + 60).to_i.to_s - @exception = TooManyRequests.new(response: response) + @exception = TooManyRequests.new(response:) end end def test_initialize_with_empty_response response = Net::HTTPTooManyRequests.new("1.1", 429, "Too Many Requests") - exception = TooManyRequests.new(response: response) + exception = TooManyRequests.new(response:) assert_equal 0, exception.rate_limits.count assert_equal Time.at(0).utc, exception.reset_at diff --git a/x.gemspec b/x.gemspec index bd3e264..1d2a0cc 100644 --- a/x.gemspec +++ b/x.gemspec @@ -9,7 +9,7 @@ Gem::Specification.new do |spec| spec.summary = "A Ruby interface to the X API." spec.homepage = "https://sferik.github.io/x-ruby" spec.license = "MIT" - spec.required_ruby_version = ">= 3.0" + spec.required_ruby_version = ">= 3.2" spec.platform = Gem::Platform::RUBY spec.metadata = {