response_with_limit_adapter_spec.rb 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. # frozen_string_literal: true
  2. require 'rails_helper'
  3. RSpec.describe Paperclip::ResponseWithLimitAdapter do
  4. subject { described_class.new(response_with_limit) }
  5. before { stub_request(:get, url).to_return(headers: headers, body: body) }
  6. let(:response_with_limit) { ResponseWithLimit.new(response, 50.kilobytes) }
  7. let(:response) { Request.new(:get, url).perform(&:itself) }
  8. let(:url) { 'https://example.com/dir/foo.png' }
  9. let(:headers) { nil }
  10. let(:body) { attachment_fixture('600x400.jpeg').binmode.read }
  11. it 'writes temporary file' do
  12. expect(subject.tempfile.read).to eq body
  13. expect(subject.size).to eq body.bytesize
  14. end
  15. context 'with Content-Disposition header' do
  16. let(:headers) { { 'Content-Disposition' => 'attachment; filename="bar.png"' } }
  17. it 'uses filename from header' do
  18. expect(subject.original_filename).to eq 'bar.png'
  19. end
  20. it 'detects MIME type from content' do
  21. expect(subject.content_type).to eq 'image/jpeg'
  22. end
  23. end
  24. context 'without Content-Disposition header' do
  25. it 'uses filename from path' do
  26. expect(subject.original_filename).to eq 'foo.png'
  27. end
  28. it 'detects MIME type from content' do
  29. expect(subject.content_type).to eq 'image/jpeg'
  30. end
  31. end
  32. context 'without filename in path' do
  33. let(:url) { 'https://example.com/' }
  34. it 'falls back to "data"' do
  35. expect(subject.original_filename).to eq 'data'
  36. end
  37. it 'detects MIME type from content' do
  38. expect(subject.content_type).to eq 'image/jpeg'
  39. end
  40. end
  41. context 'with very long filename' do
  42. let(:url) { 'https://example.com/abcdefghijklmnopqrstuvwxyz.0123456789' }
  43. it 'truncates the filename' do
  44. expect(subject.original_filename).to eq 'abcdefghijklmnopqrst.0123'
  45. end
  46. end
  47. context 'when response size exceeds limit' do
  48. context 'with Content-Length header' do
  49. let(:headers) { { 'Content-Length' => 5.megabytes } }
  50. it 'raises without reading the body' do
  51. allow(response).to receive(:body).and_call_original
  52. expect { subject }.to raise_error(Mastodon::LengthValidationError, 'Content-Length 5242880 exceeds limit of 51200')
  53. expect(response).to_not have_received(:body)
  54. end
  55. end
  56. context 'without Content-Length header' do
  57. let(:body) { SecureRandom.random_bytes(1.megabyte) }
  58. it 'raises while reading the body' do
  59. expect { subject }.to raise_error(Mastodon::LengthValidationError, 'Body size exceeds limit of 51200')
  60. expect(response.content_length).to be_nil
  61. end
  62. end
  63. end
  64. context 'when response times out' do
  65. it 'raises' do
  66. allow(response.body.connection).to receive(:readpartial).and_raise(HTTP::TimeoutError)
  67. expect { subject }.to raise_error(HTTP::TimeoutError)
  68. end
  69. end
  70. end