このコミットが含まれているのは:
2026-11-01 18:18:54 +09:00
コミット 22e57564a5
18個のファイルの変更、313行の追加、121行の削除
+23 -3
ファイルの表示
@@ -211,18 +211,37 @@ RSpec.describe 'Counts download acknowledgement' do
end
RSpec.describe CountsExportDownload::ResponseBody do
it 'survives Rails buffer enumeration without closing before the first byte' do
Dir.mktmpdir('counts-body-spec') do |directory|
path = File.join(directory, 'file')
payload = 'data' * 20_000
File.binwrite(path, payload)
states = []
source = ActionDispatch::Response::FileBody.new(path)
body = described_class.new(source) { |state| states << state; true }
response = ActionDispatch::Response.new
response.body = body
deferred = response.stream.to_ary
expect(states).to eq([])
expect(deferred.to_a.join).to eq(payload)
expect(states.count('started')).to eq(1)
end
end
it 'acknowledges only after the first Rack yield and closes its bounded file body' do
Dir.mktmpdir('counts-body-spec') do |directory|
path = File.join(directory, 'file')
File.binwrite(path, 'x' * (64 * 1024 + 3))
states = []
body = described_class.new(path) { |state| states << state; true }
source = ActionDispatch::Response::FileBody.new(path)
body = described_class.new(source) { |state| states << state; true }
chunks = []
body.each do |chunk|
expect(states).not_to include('started') if chunks.empty?
chunks << chunk
end
expect(chunks.map(&:bytesize)).to eq([64 * 1024, 3])
expect(chunks.join).to eq('x' * (64 * 1024 + 3))
expect(chunks.map(&:bytesize).max).to be <= 64 * 1024
expect(states.count('started')).to eq(1)
expect(body).not_to respond_to(:to_path)
expect { body.close }.not_to raise_error
@@ -234,7 +253,8 @@ RSpec.describe CountsExportDownload::ResponseBody do
path = File.join(directory, 'file')
File.binwrite(path, 'data')
states = []
body = described_class.new(path) { |state| states << state; true }
source = ActionDispatch::Response::FileBody.new(path)
body = described_class.new(source) { |state| states << state; true }
expect { body.each { raise IOError, 'connection closed' } }.to raise_error(IOError)
expect(states).to include('failed')
expect(states).not_to include('started')