広場投稿追加画面の刷新 (#399) (#413)

Reviewed-on: #413
Co-authored-by: miteruzo <miteruzo@naver.com>
Co-committed-by: miteruzo <miteruzo@naver.com>
このコミットはPull リクエスト #413 でマージされました.
このコミットが含まれているのは:
2026-07-19 00:03:10 +09:00
committed by みてるぞ
コミット f1181e8510
99個のファイルの変更10242行の追加1126行の削除
+63 -10
ファイルの表示
@@ -2,7 +2,7 @@ require 'rails_helper'
RSpec.describe Preview::ThumbnailFetcher do
describe '.fetch' do
it 'rejects svg thumbnails' do
it 'accepts svg thumbnails for the common safe rasterisation path' do
page = Preview::HttpFetcher::Response.new(
'<meta property="og:image" content="https://example.com/thumb.svg">',
'text/html',
@@ -12,8 +12,9 @@ RSpec.describe Preview::ThumbnailFetcher do
'image/svg+xml',
'https://example.com/thumb.svg')
allow(Preview::UrlSafety).to receive(:validate)
.and_return([URI.parse('https://example.com/page'), ['203.0.113.10']])
allow(Preview::UrlSafety).to receive(:validate) do |url|
[URI.parse(url), ['203.0.113.10']]
end
allow(Preview::HttpFetcher).to receive(:fetch)
.with('https://example.com/page', max_bytes: described_class::HTML_MAX_BYTES)
.and_return(page)
@@ -21,9 +22,7 @@ RSpec.describe Preview::ThumbnailFetcher do
.with('https://example.com/thumb.svg')
.and_return(svg)
expect {
described_class.fetch('https://example.com/page')
}.to raise_error(Preview::ThumbnailFetcher::GenerationFailed)
expect(described_class.fetch('https://example.com/page')).to eq('<svg></svg>')
end
it 'accepts allowed image content type with parameters' do
@@ -32,12 +31,13 @@ RSpec.describe Preview::ThumbnailFetcher do
'text/html',
'https://example.com/page')
image = Preview::HttpFetcher::Response.new(
'jpeg-bytes',
"\xFF\xD8\xFFjpeg-bytes".b,
'image/jpeg; charset=binary',
'https://example.com/thumb.jpg')
allow(Preview::UrlSafety).to receive(:validate)
.and_return([URI.parse('https://example.com/page'), ['203.0.113.10']])
allow(Preview::UrlSafety).to receive(:validate) do |url|
[URI.parse(url), ['203.0.113.10']]
end
allow(Preview::HttpFetcher).to receive(:fetch)
.with('https://example.com/page', max_bytes: described_class::HTML_MAX_BYTES)
.and_return(page)
@@ -45,7 +45,60 @@ RSpec.describe Preview::ThumbnailFetcher do
.with('https://example.com/thumb.jpg')
.and_return(image)
expect(described_class.fetch('https://example.com/page')).to eq('jpeg-bytes')
expect(described_class.fetch('https://example.com/page'))
.to eq("\xFF\xD8\xFFjpeg-bytes".b)
end
end
describe '.fetch_image_response' do
it 'rejects an unsafe input URL before HTTP fetch' do
allow(Preview::UrlSafety).to receive(:validate)
.and_raise(Preview::UrlSafety::UnsafeUrl, '安全でない接続先は使用できません.')
expect(Preview::HttpFetcher).not_to receive(:fetch)
expect {
described_class.fetch_image_response('https://unsafe.example.com/thumb.jpg')
}.to raise_error(Preview::UrlSafety::UnsafeUrl, '安全でない接続先は使用できません.')
end
it 'rejects an unsafe redirect target' do
allow(Preview::UrlSafety).to receive(:validate)
.and_return([URI.parse('https://example.com/thumb.jpg'), ['8.8.8.8']])
allow(Preview::HttpFetcher).to receive(:fetch)
.with('https://example.com/thumb.jpg')
.and_raise(Preview::UrlSafety::UnsafeUrl, '安全でない接続先は使用できません.')
expect {
described_class.fetch_image_response('https://example.com/thumb.jpg')
}.to raise_error(Preview::UrlSafety::UnsafeUrl, '安全でない接続先は使用できません.')
end
it 'rejects an oversized image response' do
allow(Preview::UrlSafety).to receive(:validate)
.and_return([URI.parse('https://example.com/thumb.jpg'), ['8.8.8.8']])
allow(Preview::HttpFetcher).to receive(:fetch)
.with('https://example.com/thumb.jpg')
.and_raise(Preview::HttpFetcher::ResponseTooLarge, 'too large')
expect {
described_class.fetch_image_response('https://example.com/thumb.jpg')
}.to raise_error(Preview::HttpFetcher::ResponseTooLarge)
end
it 'rejects a non-image content type' do
allow(Preview::UrlSafety).to receive(:validate)
.and_return([URI.parse('https://example.com/thumb.jpg'), ['8.8.8.8']])
allow(Preview::HttpFetcher).to receive(:fetch)
.with('https://example.com/thumb.jpg')
.and_return(
Preview::HttpFetcher::Response.new(
'<html></html>',
'text/html',
'https://example.com/thumb.jpg'))
expect {
described_class.fetch_image_response('https://example.com/thumb.jpg')
}.to raise_error(Preview::ThumbnailFetcher::GenerationFailed)
end
end
end