Add bin and edit workflow
Gitea Actions Demo / Explore-Gitea-Actions (push) Failing after 9s

This commit is contained in:
2026-09-16 13:11:16 -06:00
parent c8ac4fcae5
commit 4cee170d66
17576 changed files with 895740 additions and 2 deletions
@@ -0,0 +1,14 @@
# frozen_string_literal: true
# Allows to disable WebMock stubs
module DisablingStub
def disable
@disabled = true
end
def disabled?
@disabled
end
WebMock::RequestStub.prepend self
end
@@ -0,0 +1,15 @@
# frozen_string_literal: true
# emulates ActiveSupport::SafeBuffer#gsub
FakeSafeBuffer = Struct.new(:string) do
def to_s
self
end
def gsub(regex)
string.gsub(regex) do
match, = Regexp.last_match(0), '' =~ /a/ # rubocop:disable Performance/StringInclude
yield(match)
end
end
end
@@ -0,0 +1,96 @@
# frozen_string_literal: true
module Faraday
module HelperMethods
def self.included(base)
base.extend ClassMethods
end
module ClassMethods
def features(*features)
@features = features
end
def on_feature(name)
yield if block_given? && feature?(name)
end
def feature?(name)
if @features.nil?
superclass.feature?(name) if superclass.respond_to?(:feature?)
elsif @features.include?(name)
true
end
end
def method_with_body?(method)
METHODS_WITH_BODY.include?(method.to_s)
end
end
def ssl_mode?
ENV['SSL'] == 'yes'
end
def normalize(url)
Faraday::Utils::URI(url)
end
def with_default_uri_parser(parser)
old_parser = Faraday::Utils.default_uri_parser
begin
Faraday::Utils.default_uri_parser = parser
yield
ensure
Faraday::Utils.default_uri_parser = old_parser
end
end
def with_env(new_env)
old_env = {}
new_env.each do |key, value|
old_env[key] = ENV.fetch(key, false)
ENV[key] = value
end
begin
yield
ensure
old_env.each do |key, value|
value == false ? ENV.delete(key) : ENV[key] = value
end
end
end
def with_env_proxy_disabled
Faraday.ignore_env_proxy = true
begin
yield
ensure
Faraday.ignore_env_proxy = false
end
end
def capture_warnings
old = $stderr
$stderr = StringIO.new
begin
yield
$stderr.string
ensure
$stderr = old
end
end
def method_with_body?(method)
self.class.method_with_body?(method)
end
def big_string
kb = 1024
(32..126).map(&:chr).cycle.take(50 * kb).join
end
end
end
@@ -0,0 +1,105 @@
# frozen_string_literal: true
shared_examples 'an adapter' do |**options|
before { skip } if options[:skip]
context 'with SSL enabled' do
before { ENV['SSL'] = 'yes' }
include_examples 'adapter examples', options
end
context 'with SSL disabled' do
before { ENV['SSL'] = 'no' }
include_examples 'adapter examples', options
end
end
shared_examples 'adapter examples' do |**options|
include Faraday::StreamingResponseChecker
let(:adapter) { described_class.name.split('::').last }
let(:conn_options) { { headers: { 'X-Faraday-Adapter' => adapter } }.merge(options[:conn_options] || {}) }
let(:adapter_options) do
return [] unless options[:adapter_options]
if options[:adapter_options].is_a?(Array)
options[:adapter_options]
else
[options[:adapter_options]]
end
end
let(:protocol) { ssl_mode? ? 'https' : 'http' }
let(:remote) { "#{protocol}://example.com" }
let(:stub_remote) { remote }
let(:conn) do
conn_options[:ssl] ||= {}
conn_options[:ssl][:ca_file] ||= ENV.fetch('SSL_FILE', nil)
conn_options[:ssl][:verify_hostname] ||= ENV['SSL_VERIFY_HOSTNAME'] == 'yes'
Faraday.new(remote, conn_options) do |conn|
conn.request :url_encoded
conn.response :raise_error
conn.adapter described_class, *adapter_options
end
end
let!(:request_stub) { stub_request(http_method, stub_remote) }
after do
expect(request_stub).to have_been_requested unless request_stub.disabled?
end
describe '#delete' do
let(:http_method) { :delete }
it_behaves_like 'a request method', :delete
end
describe '#get' do
let(:http_method) { :get }
it_behaves_like 'a request method', :get
end
describe '#head' do
let(:http_method) { :head }
it_behaves_like 'a request method', :head
end
describe '#options' do
let(:http_method) { :options }
it_behaves_like 'a request method', :options
end
describe '#patch' do
let(:http_method) { :patch }
it_behaves_like 'a request method', :patch
end
describe '#post' do
let(:http_method) { :post }
it_behaves_like 'a request method', :post
end
describe '#put' do
let(:http_method) { :put }
it_behaves_like 'a request method', :put
end
on_feature :trace_method do
describe '#trace' do
let(:http_method) { :trace }
it_behaves_like 'a request method', :trace
end
end
end
@@ -0,0 +1,18 @@
# frozen_string_literal: true
shared_examples 'a params encoder' do
it 'escapes safe buffer' do
monies = FakeSafeBuffer.new('$32,000.00')
expect(subject.encode('a' => monies)).to eq('a=%2432%2C000.00')
end
it 'raises type error for empty string' do
expect { subject.encode('') }.to raise_error(TypeError) do |error|
expect(error.message).to eq("Can't convert String into Hash.")
end
end
it 'encodes nil' do
expect(subject.encode('a' => nil)).to eq('a')
end
end
@@ -0,0 +1,263 @@
# frozen_string_literal: true
shared_examples 'proxy examples' do
it 'handles requests with proxy' do
res = conn.public_send(http_method, '/')
expect(res.status).to eq(200)
end
it 'handles proxy failures' do
request_stub.to_return(status: 407)
expect { conn.public_send(http_method, '/') }.to raise_error(Faraday::ProxyAuthError)
end
end
shared_examples 'a request method' do |http_method|
let(:query_or_body) { method_with_body?(http_method) ? :body : :query }
let(:response) { conn.public_send(http_method, '/') }
unless http_method == :head && feature?(:skip_response_body_on_head)
it 'retrieves the response body' do
res_body = 'test'
request_stub.to_return(body: res_body)
expect(conn.public_send(http_method, '/').body).to eq(res_body)
end
end
it 'handles headers with multiple values' do
request_stub.to_return(headers: { 'Set-Cookie' => 'name=value' })
expect(response.headers['set-cookie']).to eq('name=value')
end
it 'retrieves the response headers' do
request_stub.to_return(headers: { 'Content-Type' => 'text/plain' })
expect(response.headers['Content-Type']).to match(%r{text/plain})
expect(response.headers['content-type']).to match(%r{text/plain})
end
it 'sends user agent' do
request_stub.with(headers: { 'User-Agent' => 'Agent Faraday' })
conn.public_send(http_method, '/', nil, user_agent: 'Agent Faraday')
end
it 'represents empty body response as blank string' do
expect(response.body).to eq('')
end
it 'handles connection error' do
request_stub.disable
expect { conn.public_send(http_method, 'http://localhost:4') }.to raise_error(Faraday::ConnectionFailed)
end
on_feature :local_socket_binding do
it 'binds local socket' do
stub_request(http_method, 'http://example.com')
host = '1.2.3.4'
port = 1234
conn_options[:request] = { bind: { host: host, port: port } }
conn.public_send(http_method, '/')
expect(conn.options[:bind][:host]).to eq(host)
expect(conn.options[:bind][:port]).to eq(port)
end
end
# context 'when wrong ssl certificate is provided' do
# let(:ca_file_path) { 'tmp/faraday-different-ca-cert.crt' }
# before { conn_options.merge!(ssl: { ca_file: ca_file_path }) }
#
# it do
# expect { conn.public_send(http_method, '/') }.to raise_error(Faraday::SSLError) # do |ex|
# expect(ex.message).to include?('certificate')
# end
# end
# end
on_feature :request_body_on_query_methods do
it 'sends request body' do
request_stub.with({ body: 'test' })
res = if query_or_body == :body
conn.public_send(http_method, '/', 'test')
else
conn.public_send(http_method, '/') do |req|
req.body = 'test'
end
end
expect(res.env.request_body).to eq('test')
end
end
it 'sends url encoded parameters' do
payload = { name: 'zack' }
request_stub.with({ query_or_body => payload })
res = conn.public_send(http_method, '/', payload)
if query_or_body == :query
expect(res.env.request_body).to be_nil
else
expect(res.env.request_body).to eq('name=zack')
end
end
it 'sends url encoded nested parameters' do
payload = { name: { first: 'zack' } }
request_stub.with({ query_or_body => payload })
conn.public_send(http_method, '/', payload)
end
# TODO: This needs reimplementation: see https://github.com/lostisland/faraday/issues/718
# Should raise Faraday::TimeoutError
it 'supports timeout option' do
conn_options[:request] = { timeout: 1 }
request_stub.to_timeout
exc = adapter == 'NetHttp' ? Faraday::ConnectionFailed : Faraday::TimeoutError
expect { conn.public_send(http_method, '/') }.to raise_error(exc)
end
# TODO: This needs reimplementation: see https://github.com/lostisland/faraday/issues/718
# Should raise Faraday::ConnectionFailed
it 'supports open_timeout option' do
conn_options[:request] = { open_timeout: 1 }
request_stub.to_timeout
exc = adapter == 'NetHttp' ? Faraday::ConnectionFailed : Faraday::TimeoutError
expect { conn.public_send(http_method, '/') }.to raise_error(exc)
end
on_feature :reason_phrase_parse do
it 'parses the reason phrase' do
request_stub.to_return(status: [200, 'OK'])
expect(response.reason_phrase).to eq('OK')
end
end
on_feature :compression do
# Accept-Encoding header not sent for HEAD requests as body is not expected in the response.
unless http_method == :head
it 'handles gzip compression' do
request_stub.with(headers: { 'Accept-Encoding' => /\bgzip\b/ })
conn.public_send(http_method, '/')
end
it 'handles deflate compression' do
request_stub.with(headers: { 'Accept-Encoding' => /\bdeflate\b/ })
conn.public_send(http_method, '/')
end
end
end
on_feature :streaming do
describe 'streaming' do
let(:streamed) { [] }
context 'when response is empty' do
it 'handles streaming' do
env = nil
conn.public_send(http_method, '/') do |req|
req.options.on_data = proc do |chunk, size, block_env|
streamed << [chunk, size]
env ||= block_env
end
end
expect(streamed).to eq([['', 0]])
# TODO: enable this after updating all existing adapters to the new streaming API
# expect(env).to be_a(Faraday::Env)
# expect(env.status).to eq(200)
end
end
context 'when response contains big data' do
before { request_stub.to_return(body: big_string) }
it 'handles streaming' do
env = nil
response = conn.public_send(http_method, '/') do |req|
req.options.on_data = proc do |chunk, size, block_env|
streamed << [chunk, size]
env ||= block_env
end
end
expect(response.body).to eq('')
check_streaming_response(streamed, chunk_size: 16 * 1024)
# TODO: enable this after updating all existing adapters to the new streaming API
# expect(env).to be_a(Faraday::Env)
# expect(env.status).to eq(200)
end
end
end
end
on_feature :parallel do
context 'with parallel setup' do
before do
@resp1 = nil
@resp2 = nil
@payload1 = { a: '1' }
@payload2 = { b: '2' }
request_stub
.with({ query_or_body => @payload1 })
.to_return(body: @payload1.to_json)
stub_request(http_method, remote)
.with({ query_or_body => @payload2 })
.to_return(body: @payload2.to_json)
conn.in_parallel do
@resp1 = conn.public_send(http_method, '/', @payload1)
@resp2 = conn.public_send(http_method, '/', @payload2)
expect(conn.in_parallel?).to be_truthy
expect(@resp1.body).to be_nil
expect(@resp2.body).to be_nil
end
expect(conn.in_parallel?).to be_falsey
end
it 'handles parallel requests status' do
expect(@resp1&.status).to eq(200)
expect(@resp2&.status).to eq(200)
end
unless http_method == :head && feature?(:skip_response_body_on_head)
it 'handles parallel requests body' do
expect(@resp1&.body).to eq(@payload1.to_json)
expect(@resp2&.body).to eq(@payload2.to_json)
end
end
end
end
context 'when a proxy is provided as option' do
before do
conn_options[:proxy] = 'http://env-proxy.com:80'
end
include_examples 'proxy examples'
end
context 'when http_proxy env variable is set' do
let(:proxy_url) { 'http://env-proxy.com:80' }
around do |example|
with_env 'http_proxy' => proxy_url do
example.run
end
end
include_examples 'proxy examples'
context 'when the env proxy is ignored' do
around do |example|
with_env_proxy_disabled(&example)
end
include_examples 'proxy examples'
end
end
end
@@ -0,0 +1,35 @@
# frozen_string_literal: true
module Faraday
module StreamingResponseChecker
def check_streaming_response(streamed, options = {})
opts = {
prefix: '',
streaming?: true
}.merge(options)
expected_response = opts[:prefix] + big_string
chunks, sizes = streamed.transpose
# Check that the total size of the chunks (via the last size returned)
# is the same size as the expected_response
expect(sizes.last).to eq(expected_response.bytesize)
start_index = 0
expected_chunks = []
chunks.each do |actual_chunk|
expected_chunk = expected_response[start_index..((start_index + actual_chunk.bytesize) - 1)]
expected_chunks << expected_chunk
start_index += expected_chunk.bytesize
end
# it's easier to read a smaller portion, so we check that first
expect(expected_chunks[0][0..255]).to eq(chunks[0][0..255])
[expected_chunks, chunks].transpose.each do |expected, actual|
expect(actual).to eq(expected)
end
end
end
end