DEV: Make `CookedPostProcessor#post_process_images` method private.
This commit is contained in:
parent
baf7eac704
commit
f54e4b71b1
|
@ -65,15 +65,6 @@ class CookedPostProcessor
|
||||||
BadgeGranter.grant(Badge.find(Badge::FirstReplyByEmail), @post.user, post_id: @post.id) if @post.is_reply_by_email?
|
BadgeGranter.grant(Badge.find(Badge::FirstReplyByEmail), @post.user, post_id: @post.id) if @post.is_reply_by_email?
|
||||||
end
|
end
|
||||||
|
|
||||||
def post_process_images
|
|
||||||
extract_images.each do |img|
|
|
||||||
unless add_image_placeholder!(img)
|
|
||||||
limit_size!(img)
|
|
||||||
convert_to_link!(img)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def post_process_quotes
|
def post_process_quotes
|
||||||
@doc.css("aside.quote").each do |q|
|
@doc.css("aside.quote").each do |q|
|
||||||
post_number = q['data-post']
|
post_number = q['data-post']
|
||||||
|
@ -688,6 +679,15 @@ class CookedPostProcessor
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def post_process_images
|
||||||
|
extract_images.each do |img|
|
||||||
|
unless add_image_placeholder!(img)
|
||||||
|
limit_size!(img)
|
||||||
|
convert_to_link!(img)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def process_inline_onebox(element)
|
def process_inline_onebox(element)
|
||||||
inline_onebox = InlineOneboxer.lookup(
|
inline_onebox = InlineOneboxer.lookup(
|
||||||
element.attributes["href"].value,
|
element.attributes["href"].value,
|
||||||
|
|
|
@ -6,11 +6,7 @@ require "file_store/s3_store"
|
||||||
|
|
||||||
describe CookedPostProcessor do
|
describe CookedPostProcessor do
|
||||||
context "#post_process" do
|
context "#post_process" do
|
||||||
fab!(:upload) do
|
fab!(:upload) { Fabricate(:upload) }
|
||||||
Fabricate(:upload,
|
|
||||||
url: '/uploads/default/original/1X/1/1234567890123456.jpg'
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
fab!(:post) do
|
fab!(:post) do
|
||||||
Fabricate(:post, raw: <<~RAW)
|
Fabricate(:post, raw: <<~RAW)
|
||||||
|
@ -254,409 +250,408 @@ describe CookedPostProcessor do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
context "#post_process_images" do
|
|
||||||
|
|
||||||
before do
|
|
||||||
SiteSetting.responsive_post_image_sizes = ""
|
|
||||||
end
|
|
||||||
|
|
||||||
context "responsive images" do
|
|
||||||
before { SiteSetting.responsive_post_image_sizes = "1|1.5|3" }
|
|
||||||
|
|
||||||
it "includes responsive images on demand" do
|
|
||||||
upload = Fabricate(:upload, width: 2000, height: 1500, filesize: 10000)
|
|
||||||
post = Fabricate(:post, raw: "hello <img src='#{upload.url}'>")
|
|
||||||
|
|
||||||
# fake some optimized images
|
|
||||||
OptimizedImage.create!(
|
|
||||||
url: '/uploads/default/666x500.jpg',
|
|
||||||
width: 666,
|
|
||||||
height: 500,
|
|
||||||
upload_id: upload.id,
|
|
||||||
sha1: SecureRandom.hex,
|
|
||||||
extension: '.jpg',
|
|
||||||
filesize: 500,
|
|
||||||
version: OptimizedImage::VERSION
|
|
||||||
)
|
|
||||||
|
|
||||||
# fake 3x optimized image, we lose 2 pixels here over original due to rounding on downsize
|
|
||||||
OptimizedImage.create!(
|
|
||||||
url: '/uploads/default/1998x1500.jpg',
|
|
||||||
width: 1998,
|
|
||||||
height: 1500,
|
|
||||||
upload_id: upload.id,
|
|
||||||
sha1: SecureRandom.hex,
|
|
||||||
extension: '.jpg',
|
|
||||||
filesize: 800
|
|
||||||
)
|
|
||||||
|
|
||||||
# Fake a loading image
|
|
||||||
optimized_image = OptimizedImage.create!(
|
|
||||||
url: '/uploads/default/10x10.png',
|
|
||||||
width: CookedPostProcessor::LOADING_SIZE,
|
|
||||||
height: CookedPostProcessor::LOADING_SIZE,
|
|
||||||
upload_id: upload.id,
|
|
||||||
sha1: SecureRandom.hex,
|
|
||||||
extension: '.png',
|
|
||||||
filesize: 123
|
|
||||||
)
|
|
||||||
|
|
||||||
cpp = CookedPostProcessor.new(post)
|
|
||||||
|
|
||||||
cpp.add_to_size_cache(upload.url, 2000, 1500)
|
|
||||||
cpp.post_process_images
|
|
||||||
cpp.optimize_urls
|
|
||||||
|
|
||||||
html = cpp.html
|
|
||||||
|
|
||||||
expect(html).to include(%Q|data-small-upload="//test.localhost/uploads/default/10x10.png"|)
|
|
||||||
# 1.5x is skipped cause we have a missing thumb
|
|
||||||
expect(html).to include('srcset="//test.localhost/uploads/default/666x500.jpg, //test.localhost/uploads/default/1998x1500.jpg 3x"')
|
|
||||||
expect(html).to include('src="//test.localhost/uploads/default/666x500.jpg"')
|
|
||||||
|
|
||||||
# works with CDN
|
|
||||||
set_cdn_url("http://cdn.localhost")
|
|
||||||
|
|
||||||
cpp = CookedPostProcessor.new(post)
|
|
||||||
cpp.add_to_size_cache(upload.url, 2000, 1500)
|
|
||||||
cpp.post_process_images
|
|
||||||
cpp.optimize_urls
|
|
||||||
|
|
||||||
html = cpp.html
|
|
||||||
|
|
||||||
expect(html).to include(%Q|data-small-upload="//cdn.localhost/uploads/default/10x10.png"|)
|
|
||||||
expect(html).to include('srcset="//cdn.localhost/uploads/default/666x500.jpg, //cdn.localhost/uploads/default/1998x1500.jpg 3x"')
|
|
||||||
expect(html).to include('src="//cdn.localhost/uploads/default/666x500.jpg"')
|
|
||||||
end
|
|
||||||
|
|
||||||
it "doesn't include response images for cropped images" do
|
|
||||||
upload = Fabricate(:upload, width: 200, height: 4000, filesize: 12345)
|
|
||||||
post = Fabricate(:post, raw: "hello <img src='#{upload.url}'>")
|
|
||||||
|
|
||||||
# fake some optimized images
|
|
||||||
OptimizedImage.create!(
|
|
||||||
url: 'http://a.b.c/200x500.jpg',
|
|
||||||
width: 200,
|
|
||||||
height: 500,
|
|
||||||
upload_id: upload.id,
|
|
||||||
sha1: SecureRandom.hex,
|
|
||||||
extension: '.jpg',
|
|
||||||
filesize: 500
|
|
||||||
)
|
|
||||||
|
|
||||||
cpp = CookedPostProcessor.new(post)
|
|
||||||
cpp.add_to_size_cache(upload.url, 200, 4000)
|
|
||||||
cpp.post_process_images
|
|
||||||
cpp.optimize_urls
|
|
||||||
|
|
||||||
expect(cpp.html).to_not include('srcset="')
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
shared_examples "leave dimensions alone" do
|
|
||||||
it "doesn't use them" do
|
|
||||||
expect(cpp.html).to match(/src="http:\/\/foo.bar\/image.png" width="" height=""/)
|
|
||||||
expect(cpp.html).to match(/src="http:\/\/domain.com\/picture.jpg" width="50" height="42"/)
|
|
||||||
expect(cpp).to be_dirty
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context "with image_sizes" do
|
|
||||||
fab!(:post) { Fabricate(:post_with_image_urls) }
|
|
||||||
let(:cpp) { CookedPostProcessor.new(post, image_sizes: image_sizes) }
|
|
||||||
|
|
||||||
|
context "processing images" do
|
||||||
before do
|
before do
|
||||||
cpp.post_process_images
|
SiteSetting.responsive_post_image_sizes = ""
|
||||||
cpp.optimize_urls
|
|
||||||
end
|
end
|
||||||
|
|
||||||
context "valid" do
|
context "responsive images" do
|
||||||
let(:image_sizes) { { "http://foo.bar/image.png" => { "width" => 111, "height" => 222 } } }
|
before { SiteSetting.responsive_post_image_sizes = "1|1.5|3" }
|
||||||
|
|
||||||
it "uses them" do
|
it "includes responsive images on demand" do
|
||||||
expect(cpp.html).to match(/src="http:\/\/foo.bar\/image.png" width="111" height="222"/)
|
upload = Fabricate(:upload, width: 2000, height: 1500, filesize: 10000)
|
||||||
|
post = Fabricate(:post, raw: "hello <img src='#{upload.url}'>")
|
||||||
|
|
||||||
|
# fake some optimized images
|
||||||
|
OptimizedImage.create!(
|
||||||
|
url: '/uploads/default/666x500.jpg',
|
||||||
|
width: 666,
|
||||||
|
height: 500,
|
||||||
|
upload_id: upload.id,
|
||||||
|
sha1: SecureRandom.hex,
|
||||||
|
extension: '.jpg',
|
||||||
|
filesize: 500,
|
||||||
|
version: OptimizedImage::VERSION
|
||||||
|
)
|
||||||
|
|
||||||
|
# fake 3x optimized image, we lose 2 pixels here over original due to rounding on downsize
|
||||||
|
OptimizedImage.create!(
|
||||||
|
url: '/uploads/default/1998x1500.jpg',
|
||||||
|
width: 1998,
|
||||||
|
height: 1500,
|
||||||
|
upload_id: upload.id,
|
||||||
|
sha1: SecureRandom.hex,
|
||||||
|
extension: '.jpg',
|
||||||
|
filesize: 800
|
||||||
|
)
|
||||||
|
|
||||||
|
# Fake a loading image
|
||||||
|
optimized_image = OptimizedImage.create!(
|
||||||
|
url: '/uploads/default/10x10.png',
|
||||||
|
width: CookedPostProcessor::LOADING_SIZE,
|
||||||
|
height: CookedPostProcessor::LOADING_SIZE,
|
||||||
|
upload_id: upload.id,
|
||||||
|
sha1: SecureRandom.hex,
|
||||||
|
extension: '.png',
|
||||||
|
filesize: 123
|
||||||
|
)
|
||||||
|
|
||||||
|
cpp = CookedPostProcessor.new(post)
|
||||||
|
|
||||||
|
cpp.add_to_size_cache(upload.url, 2000, 1500)
|
||||||
|
cpp.post_process
|
||||||
|
|
||||||
|
html = cpp.html
|
||||||
|
|
||||||
|
expect(html).to include(%Q|data-small-upload="//test.localhost/uploads/default/10x10.png"|)
|
||||||
|
# 1.5x is skipped cause we have a missing thumb
|
||||||
|
expect(html).to include('srcset="//test.localhost/uploads/default/666x500.jpg, //test.localhost/uploads/default/1998x1500.jpg 3x"')
|
||||||
|
expect(html).to include('src="//test.localhost/uploads/default/666x500.jpg"')
|
||||||
|
|
||||||
|
# works with CDN
|
||||||
|
set_cdn_url("http://cdn.localhost")
|
||||||
|
|
||||||
|
cpp = CookedPostProcessor.new(post)
|
||||||
|
cpp.add_to_size_cache(upload.url, 2000, 1500)
|
||||||
|
cpp.post_process
|
||||||
|
|
||||||
|
html = cpp.html
|
||||||
|
|
||||||
|
expect(html).to include(%Q|data-small-upload="//cdn.localhost/uploads/default/10x10.png"|)
|
||||||
|
expect(html).to include('srcset="//cdn.localhost/uploads/default/666x500.jpg, //cdn.localhost/uploads/default/1998x1500.jpg 3x"')
|
||||||
|
expect(html).to include('src="//cdn.localhost/uploads/default/666x500.jpg"')
|
||||||
|
end
|
||||||
|
|
||||||
|
it "doesn't include response images for cropped images" do
|
||||||
|
upload = Fabricate(:upload, width: 200, height: 4000, filesize: 12345)
|
||||||
|
post = Fabricate(:post, raw: "hello <img src='#{upload.url}'>")
|
||||||
|
|
||||||
|
# fake some optimized images
|
||||||
|
OptimizedImage.create!(
|
||||||
|
url: 'http://a.b.c/200x500.jpg',
|
||||||
|
width: 200,
|
||||||
|
height: 500,
|
||||||
|
upload_id: upload.id,
|
||||||
|
sha1: SecureRandom.hex,
|
||||||
|
extension: '.jpg',
|
||||||
|
filesize: 500
|
||||||
|
)
|
||||||
|
|
||||||
|
cpp = CookedPostProcessor.new(post)
|
||||||
|
cpp.add_to_size_cache(upload.url, 200, 4000)
|
||||||
|
cpp.post_process
|
||||||
|
|
||||||
|
expect(cpp.html).to_not include('srcset="')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
shared_examples "leave dimensions alone" do
|
||||||
|
it "doesn't use them" do
|
||||||
|
expect(cpp.html).to match(/src="http:\/\/foo.bar\/image.png" width="" height=""/)
|
||||||
expect(cpp.html).to match(/src="http:\/\/domain.com\/picture.jpg" width="50" height="42"/)
|
expect(cpp.html).to match(/src="http:\/\/domain.com\/picture.jpg" width="50" height="42"/)
|
||||||
expect(cpp).to be_dirty
|
expect(cpp).to be_dirty
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context "invalid width" do
|
context "with image_sizes" do
|
||||||
let(:image_sizes) { { "http://foo.bar/image.png" => { "width" => 0, "height" => 222 } } }
|
fab!(:post) { Fabricate(:post_with_image_urls) }
|
||||||
include_examples "leave dimensions alone"
|
let(:cpp) { CookedPostProcessor.new(post, image_sizes: image_sizes) }
|
||||||
end
|
|
||||||
|
|
||||||
context "invalid height" do
|
|
||||||
let(:image_sizes) { { "http://foo.bar/image.png" => { "width" => 111, "height" => 0 } } }
|
|
||||||
include_examples "leave dimensions alone"
|
|
||||||
end
|
|
||||||
|
|
||||||
context "invalid width & height" do
|
|
||||||
let(:image_sizes) { { "http://foo.bar/image.png" => { "width" => 0, "height" => 0 } } }
|
|
||||||
include_examples "leave dimensions alone"
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
context "with unsized images" do
|
|
||||||
|
|
||||||
fab!(:post) { Fabricate(:post_with_unsized_images) }
|
|
||||||
let(:cpp) { CookedPostProcessor.new(post) }
|
|
||||||
|
|
||||||
it "adds the width and height to images that don't have them" do
|
|
||||||
FastImage.expects(:size).returns([123, 456])
|
|
||||||
cpp.post_process_images
|
|
||||||
expect(cpp.html).to match(/width="123" height="456"/)
|
|
||||||
expect(cpp).to be_dirty
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
context "with large images" do
|
|
||||||
|
|
||||||
fab!(:upload) { Fabricate(:upload) }
|
|
||||||
fab!(:post) { Fabricate(:post_with_large_image) }
|
|
||||||
let(:cpp) { CookedPostProcessor.new(post, disable_loading_image: true) }
|
|
||||||
|
|
||||||
before do
|
|
||||||
SiteSetting.max_image_height = 2000
|
|
||||||
SiteSetting.create_thumbnails = true
|
|
||||||
FastImage.expects(:size).returns([1750, 2000])
|
|
||||||
end
|
|
||||||
|
|
||||||
it "generates overlay information" do
|
|
||||||
Upload.expects(:get_from_url).returns(upload)
|
|
||||||
OptimizedImage.expects(:resize).returns(true)
|
|
||||||
|
|
||||||
FileStore::BaseStore.any_instance.expects(:get_depth_for).returns(0)
|
|
||||||
|
|
||||||
cpp.post_process_images
|
|
||||||
cpp.optimize_urls
|
|
||||||
|
|
||||||
expect(cpp.html).to match_html <<~HTML
|
|
||||||
<p><div class="lightbox-wrapper"><a class="lightbox" href="//test.localhost/uploads/default/original/1X/1234567890123456.jpg" data-download-href="//test.localhost/uploads/default/#{upload.sha1}" title="logo.png"><img src="//test.localhost/uploads/default/optimized/1X/#{upload.sha1}_#{OptimizedImage::VERSION}_690x788.png" width="690" height="788"><div class="meta">
|
|
||||||
<svg class="fa d-icon d-icon-far-image svg-icon" aria-hidden="true"><use xlink:href="#far-image"></use></svg><span class="filename">logo.png</span><span class="informations">1750×2000 1.21 KB</span><svg class="fa d-icon d-icon-discourse-expand svg-icon" aria-hidden="true"><use xlink:href="#discourse-expand"></use></svg>
|
|
||||||
</div></a></div></p>
|
|
||||||
HTML
|
|
||||||
|
|
||||||
expect(cpp).to be_dirty
|
|
||||||
end
|
|
||||||
|
|
||||||
describe 'when image is inside onebox' do
|
|
||||||
let(:url) { 'https://image.com/my-avatar' }
|
|
||||||
let(:post) { Fabricate(:post, raw: url) }
|
|
||||||
|
|
||||||
before do
|
before do
|
||||||
Oneboxer.stubs(:onebox).with(url, anything).returns("<img class='onebox' src='/uploads/default/original/1X/1234567890123456.jpg' />")
|
cpp.post_process
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'should not add lightbox' do
|
context "valid" do
|
||||||
cpp.post_process_oneboxes
|
let(:image_sizes) { { "http://foo.bar/image.png" => { "width" => 111, "height" => 222 } } }
|
||||||
cpp.post_process_images
|
|
||||||
cpp.optimize_urls
|
|
||||||
|
|
||||||
expect(cpp.html).to match_html <<~HTML
|
it "uses them" do
|
||||||
<p><img class="onebox" src="//test.localhost/uploads/default/original/1X/1234567890123456.jpg" width="690" height="788"></p>
|
expect(cpp.html).to match(/src="http:\/\/foo.bar\/image.png" width="111" height="222"/)
|
||||||
HTML
|
expect(cpp.html).to match(/src="http:\/\/domain.com\/picture.jpg" width="50" height="42"/)
|
||||||
|
expect(cpp).to be_dirty
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context "invalid width" do
|
||||||
|
let(:image_sizes) { { "http://foo.bar/image.png" => { "width" => 0, "height" => 222 } } }
|
||||||
|
include_examples "leave dimensions alone"
|
||||||
|
end
|
||||||
|
|
||||||
|
context "invalid height" do
|
||||||
|
let(:image_sizes) { { "http://foo.bar/image.png" => { "width" => 111, "height" => 0 } } }
|
||||||
|
include_examples "leave dimensions alone"
|
||||||
|
end
|
||||||
|
|
||||||
|
context "invalid width & height" do
|
||||||
|
let(:image_sizes) { { "http://foo.bar/image.png" => { "width" => 0, "height" => 0 } } }
|
||||||
|
include_examples "leave dimensions alone"
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'when image is an svg' do
|
context "with unsized images" do
|
||||||
fab!(:post) do
|
|
||||||
Fabricate(:post, raw: '<img src="/uploads/default/original/1X/1234567890123456.svg">')
|
fab!(:post) { Fabricate(:post_with_unsized_images) }
|
||||||
|
let(:cpp) { CookedPostProcessor.new(post) }
|
||||||
|
|
||||||
|
it "adds the width and height to images that don't have them" do
|
||||||
|
FastImage.expects(:size).returns([123, 456])
|
||||||
|
cpp.post_process
|
||||||
|
expect(cpp.html).to match(/width="123" height="456"/)
|
||||||
|
expect(cpp).to be_dirty
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'should not add lightbox' do
|
end
|
||||||
cpp.post_process_images
|
|
||||||
cpp.optimize_urls
|
|
||||||
|
|
||||||
expect(cpp.html).to match_html <<~HTML
|
context "with large images" do
|
||||||
<p><img src="//test.localhost/uploads/default/original/1X/1234567890123456.svg" width="690" height="788"></p>
|
fab!(:upload) { Fabricate(:upload) }
|
||||||
|
|
||||||
|
fab!(:post) do
|
||||||
|
Fabricate(:post, raw: <<~HTML)
|
||||||
|
<img src="#{upload.url}">
|
||||||
HTML
|
HTML
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'when image src is an URL' do
|
let(:cpp) { CookedPostProcessor.new(post, disable_loading_image: true) }
|
||||||
let(:post) do
|
|
||||||
Fabricate(:post, raw: '<img src="http://test.discourse/uploads/default/original/1X/1234567890123456.svg?somepamas">')
|
before do
|
||||||
|
SiteSetting.max_image_height = 2000
|
||||||
|
SiteSetting.create_thumbnails = true
|
||||||
|
FastImage.expects(:size).returns([1750, 2000])
|
||||||
|
end
|
||||||
|
|
||||||
|
it "generates overlay information" do
|
||||||
|
OptimizedImage.expects(:resize).returns(true)
|
||||||
|
FileStore::BaseStore.any_instance.expects(:get_depth_for).returns(0)
|
||||||
|
|
||||||
|
cpp.post_process
|
||||||
|
|
||||||
|
expect(cpp.html).to match_html <<~HTML
|
||||||
|
<p><div class="lightbox-wrapper"><a class="lightbox" href="//test.localhost#{upload.url}" data-download-href="//test.localhost/uploads/default/#{upload.sha1}" title="logo.png"><img src="//test.localhost/uploads/default/optimized/1X/#{upload.sha1}_#{OptimizedImage::VERSION}_690x788.png" width="690" height="788"><div class="meta">
|
||||||
|
<svg class="fa d-icon d-icon-far-image svg-icon" aria-hidden="true"><use xlink:href="#far-image"></use></svg><span class="filename">logo.png</span><span class="informations">1750×2000 1.21 KB</span><svg class="fa d-icon d-icon-discourse-expand svg-icon" aria-hidden="true"><use xlink:href="#discourse-expand"></use></svg>
|
||||||
|
</div></a></div></p>
|
||||||
|
HTML
|
||||||
|
|
||||||
|
expect(cpp).to be_dirty
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'when image is inside onebox' do
|
||||||
|
let(:url) { 'https://image.com/my-avatar' }
|
||||||
|
let(:post) { Fabricate(:post, raw: url) }
|
||||||
|
|
||||||
|
before do
|
||||||
|
Oneboxer.stubs(:onebox).with(url, anything).returns("<img class='onebox' src='/uploads/default/original/1X/1234567890123456.jpg' />")
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'should not add lightbox' do
|
it 'should not add lightbox' do
|
||||||
SiteSetting.crawl_images = true
|
cpp.post_process
|
||||||
cpp.post_process_images
|
|
||||||
cpp.optimize_urls
|
|
||||||
|
|
||||||
expect(cpp.html).to match_html("<p><img src=\"http://test.discourse/uploads/default/original/1X/1234567890123456.svg?somepamas\" width=\"690\"\ height=\"788\"></p>")
|
expect(cpp.html).to match_html <<~HTML
|
||||||
|
<p><img class="onebox" src="//test.localhost/uploads/default/original/1X/1234567890123456.jpg" width="690" height="788"></p>
|
||||||
|
HTML
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe 'when image is an svg' do
|
||||||
|
fab!(:post) do
|
||||||
|
Fabricate(:post, raw: '<img src="/uploads/default/original/1X/1234567890123456.svg">')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should not add lightbox' do
|
||||||
|
cpp.post_process
|
||||||
|
|
||||||
|
expect(cpp.html).to match_html <<~HTML
|
||||||
|
<p><img src="//test.localhost/uploads/default/original/1X/1234567890123456.svg" width="690" height="788"></p>
|
||||||
|
HTML
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'when image src is an URL' do
|
||||||
|
let(:post) do
|
||||||
|
Fabricate(:post, raw: '<img src="http://test.discourse/uploads/default/original/1X/1234567890123456.svg?somepamas">')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should not add lightbox' do
|
||||||
|
SiteSetting.crawl_images = true
|
||||||
|
cpp.post_process
|
||||||
|
|
||||||
|
expect(cpp.html).to match_html("<p><img src=\"http://test.discourse/uploads/default/original/1X/1234567890123456.svg?somepamas\" width=\"690\"\ height=\"788\"></p>")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
context "with tall images" do
|
||||||
|
fab!(:upload) { Fabricate(:upload) }
|
||||||
|
|
||||||
|
fab!(:post) do
|
||||||
|
Fabricate(:post, raw: <<~HTML)
|
||||||
|
<img src="#{upload.url}">
|
||||||
|
HTML
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:cpp) { CookedPostProcessor.new(post, disable_loading_image: true) }
|
||||||
|
|
||||||
|
before do
|
||||||
|
SiteSetting.create_thumbnails = true
|
||||||
|
FastImage.expects(:size).returns([860, 2000])
|
||||||
|
OptimizedImage.expects(:resize).never
|
||||||
|
OptimizedImage.expects(:crop).returns(true)
|
||||||
|
FileStore::BaseStore.any_instance.expects(:get_depth_for).returns(0)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "crops the image" do
|
||||||
|
cpp.post_process
|
||||||
|
|
||||||
|
expect(cpp.html).to match(/width="690" height="500">/)
|
||||||
|
expect(cpp).to be_dirty
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
context "with iPhone X screenshots" do
|
||||||
|
fab!(:upload) { Fabricate(:upload) }
|
||||||
|
|
||||||
|
fab!(:post) do
|
||||||
|
Fabricate(:post, raw: <<~HTML)
|
||||||
|
<img src="#{upload.url}">
|
||||||
|
HTML
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:cpp) { CookedPostProcessor.new(post, disable_loading_image: true) }
|
||||||
|
|
||||||
|
before do
|
||||||
|
SiteSetting.create_thumbnails = true
|
||||||
|
FastImage.expects(:size).returns([1125, 2436])
|
||||||
|
OptimizedImage.expects(:resize).returns(true)
|
||||||
|
OptimizedImage.expects(:crop).never
|
||||||
|
FileStore::BaseStore.any_instance.expects(:get_depth_for).returns(0)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "crops the image" do
|
||||||
|
cpp.post_process
|
||||||
|
|
||||||
|
expect(cpp.html).to match_html <<~HTML
|
||||||
|
<p><div class="lightbox-wrapper"><a class="lightbox" href="//test.localhost#{upload.url}" data-download-href="//test.localhost/uploads/default/#{upload.sha1}" title="logo.png"><img src="//test.localhost/uploads/default/optimized/1X/#{upload.sha1}_#{OptimizedImage::VERSION}_230x500.png" width="230" height="500"><div class="meta">
|
||||||
|
<svg class="fa d-icon d-icon-far-image svg-icon" aria-hidden="true"><use xlink:href="#far-image"></use></svg><span class="filename">logo.png</span><span class="informations">1125×2436 1.21 KB</span><svg class="fa d-icon d-icon-discourse-expand svg-icon" aria-hidden="true"><use xlink:href="#discourse-expand"></use></svg>
|
||||||
|
</div></a></div></p>
|
||||||
|
HTML
|
||||||
|
|
||||||
|
expect(cpp).to be_dirty
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
context "with large images when using subfolders" do
|
||||||
|
fab!(:upload) { Fabricate(:upload) }
|
||||||
|
|
||||||
|
fab!(:post) do
|
||||||
|
Fabricate(:post, raw: <<~HTML)
|
||||||
|
<img src="/subfolder#{upload.url}">
|
||||||
|
HTML
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:cpp) { CookedPostProcessor.new(post, disable_loading_image: true) }
|
||||||
|
let(:base_url) { "http://test.localhost/subfolder" }
|
||||||
|
let(:base_uri) { "/subfolder" }
|
||||||
|
|
||||||
|
before do
|
||||||
|
SiteSetting.max_image_height = 2000
|
||||||
|
SiteSetting.create_thumbnails = true
|
||||||
|
Discourse.stubs(:base_url).returns(base_url)
|
||||||
|
Discourse.stubs(:base_uri).returns(base_uri)
|
||||||
|
FastImage.expects(:size).returns([1750, 2000])
|
||||||
|
OptimizedImage.expects(:resize).returns(true)
|
||||||
|
|
||||||
|
FileStore::BaseStore.any_instance.expects(:get_depth_for).returns(0)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "generates overlay information" do
|
||||||
|
cpp.post_process
|
||||||
|
|
||||||
|
expect(cpp.html). to match_html <<~HTML
|
||||||
|
<p><div class="lightbox-wrapper"><a class="lightbox" href="//test.localhost/subfolder#{upload.url}" data-download-href="//test.localhost/subfolder/uploads/default/#{upload.sha1}" title="logo.png"><img src="//test.localhost/subfolder/uploads/default/optimized/1X/#{upload.sha1}_#{OptimizedImage::VERSION}_690x788.png" width="690" height="788"><div class="meta">
|
||||||
|
<svg class="fa d-icon d-icon-far-image svg-icon" aria-hidden="true"><use xlink:href="#far-image"></use></svg><span class="filename">logo.png</span><span class="informations">1750×2000 1.21 KB</span><svg class="fa d-icon d-icon-discourse-expand svg-icon" aria-hidden="true"><use xlink:href="#discourse-expand"></use></svg>
|
||||||
|
</div></a></div></p>
|
||||||
|
HTML
|
||||||
|
|
||||||
|
expect(cpp).to be_dirty
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should escape the filename" do
|
||||||
|
upload.update!(original_filename: "><img src=x onerror=alert('haha')>.png")
|
||||||
|
cpp.post_process
|
||||||
|
|
||||||
|
expect(cpp.html).to match_html <<~HTML
|
||||||
|
<p><div class="lightbox-wrapper"><a class="lightbox" href="//test.localhost/subfolder#{upload.url}" data-download-href="//test.localhost/subfolder/uploads/default/#{upload.sha1}" title="&gt;&lt;img src=x onerror=alert(&#39;haha&#39;)&gt;.png"><img src="//test.localhost/subfolder/uploads/default/optimized/1X/#{upload.sha1}_#{OptimizedImage::VERSION}_690x788.png" width="690" height="788"><div class="meta">
|
||||||
|
<svg class="fa d-icon d-icon-far-image svg-icon" aria-hidden="true"><use xlink:href="#far-image"></use></svg><span class="filename">&gt;&lt;img src=x onerror=alert(&#39;haha&#39;)&gt;.png</span><span class="informations">1750×2000 1.21 KB</span><svg class="fa d-icon d-icon-discourse-expand svg-icon" aria-hidden="true"><use xlink:href="#discourse-expand"></use></svg>
|
||||||
|
</div></a></div></p>
|
||||||
|
HTML
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
context "with title" do
|
||||||
|
fab!(:upload) { Fabricate(:upload) }
|
||||||
|
|
||||||
|
fab!(:post) do
|
||||||
|
Fabricate(:post, raw: <<~HTML)
|
||||||
|
<img src="#{upload.url}" title="WAT">
|
||||||
|
HTML
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:cpp) { CookedPostProcessor.new(post, disable_loading_image: true) }
|
||||||
|
|
||||||
|
before do
|
||||||
|
SiteSetting.max_image_height = 2000
|
||||||
|
SiteSetting.create_thumbnails = true
|
||||||
|
FastImage.expects(:size).returns([1750, 2000])
|
||||||
|
OptimizedImage.expects(:resize).returns(true)
|
||||||
|
FileStore::BaseStore.any_instance.expects(:get_depth_for).returns(0)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "generates overlay information" do
|
||||||
|
cpp.post_process
|
||||||
|
|
||||||
|
expect(cpp.html).to match_html <<~HTML
|
||||||
|
<p><div class="lightbox-wrapper"><a class="lightbox" href="//test.localhost#{upload.url}" data-download-href="//test.localhost/uploads/default/#{upload.sha1}" title="WAT"><img src="//test.localhost/uploads/default/optimized/1X/#{upload.sha1}_#{OptimizedImage::VERSION}_690x788.png" title="WAT" width="690" height="788"><div class="meta">
|
||||||
|
<svg class="fa d-icon d-icon-far-image svg-icon" aria-hidden="true"><use xlink:href="#far-image"></use></svg><span class="filename">WAT</span><span class="informations">1750×2000 1.21 KB</span><svg class="fa d-icon d-icon-discourse-expand svg-icon" aria-hidden="true"><use xlink:href="#discourse-expand"></use></svg>
|
||||||
|
</div></a></div></p>
|
||||||
|
HTML
|
||||||
|
|
||||||
|
expect(cpp).to be_dirty
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
context "topic image" do
|
||||||
|
let(:topic) { build(:topic, id: 1) }
|
||||||
|
let(:post) { Fabricate(:post_with_uploaded_image, topic: topic) }
|
||||||
|
let(:cpp) { CookedPostProcessor.new(post) }
|
||||||
|
|
||||||
|
it "adds a topic image if there's one in the first post" do
|
||||||
|
FastImage.stubs(:size)
|
||||||
|
expect(post.topic.image_url).to eq(nil)
|
||||||
|
|
||||||
|
cpp.post_process
|
||||||
|
post.topic.reload
|
||||||
|
expect(post.topic.image_url).to be_present
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
context "post image" do
|
||||||
|
let(:reply) { Fabricate(:post_with_uploaded_image, post_number: 2) }
|
||||||
|
let(:cpp) { CookedPostProcessor.new(reply) }
|
||||||
|
|
||||||
context "with tall images" do
|
it "adds a post image if there's one in the post" do
|
||||||
|
FastImage.stubs(:size)
|
||||||
let(:upload) { Fabricate(:upload) }
|
expect(reply.image_url).to eq(nil)
|
||||||
let(:post) { Fabricate(:post_with_large_image) }
|
cpp.post_process
|
||||||
let(:cpp) { CookedPostProcessor.new(post, disable_loading_image: true) }
|
reply.reload
|
||||||
|
expect(reply.image_url).to be_present
|
||||||
before do
|
end
|
||||||
SiteSetting.create_thumbnails = true
|
|
||||||
|
|
||||||
Upload.expects(:get_from_url).returns(upload)
|
|
||||||
FastImage.expects(:size).returns([860, 2000])
|
|
||||||
OptimizedImage.expects(:resize).never
|
|
||||||
OptimizedImage.expects(:crop).returns(true)
|
|
||||||
|
|
||||||
FileStore::BaseStore.any_instance.expects(:get_depth_for).returns(0)
|
|
||||||
end
|
|
||||||
|
|
||||||
it "crops the image" do
|
|
||||||
cpp.post_process_images
|
|
||||||
expect(cpp.html).to match(/width="690" height="500">/)
|
|
||||||
expect(cpp).to be_dirty
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
context "with iPhone X screenshots" do
|
|
||||||
|
|
||||||
let(:upload) { Fabricate(:upload) }
|
|
||||||
let(:post) { Fabricate(:post_with_large_image) }
|
|
||||||
let(:cpp) { CookedPostProcessor.new(post, disable_loading_image: true) }
|
|
||||||
|
|
||||||
before do
|
|
||||||
SiteSetting.create_thumbnails = true
|
|
||||||
|
|
||||||
Upload.expects(:get_from_url).returns(upload)
|
|
||||||
FastImage.expects(:size).returns([1125, 2436])
|
|
||||||
OptimizedImage.expects(:resize).returns(true)
|
|
||||||
OptimizedImage.expects(:crop).never
|
|
||||||
|
|
||||||
FileStore::BaseStore.any_instance.expects(:get_depth_for).returns(0)
|
|
||||||
end
|
|
||||||
|
|
||||||
it "crops the image" do
|
|
||||||
cpp.post_process_images
|
|
||||||
cpp.optimize_urls
|
|
||||||
|
|
||||||
expect(cpp.html).to match_html <<~HTML
|
|
||||||
<p><div class="lightbox-wrapper"><a class="lightbox" href="//test.localhost/uploads/default/original/1X/1234567890123456.jpg" data-download-href="//test.localhost/uploads/default/#{upload.sha1}" title="logo.png"><img src="//test.localhost/uploads/default/optimized/1X/#{upload.sha1}_#{OptimizedImage::VERSION}_230x500.png" width="230" height="500"><div class="meta">
|
|
||||||
<svg class="fa d-icon d-icon-far-image svg-icon" aria-hidden="true"><use xlink:href="#far-image"></use></svg><span class="filename">logo.png</span><span class="informations">1125×2436 1.21 KB</span><svg class="fa d-icon d-icon-discourse-expand svg-icon" aria-hidden="true"><use xlink:href="#discourse-expand"></use></svg>
|
|
||||||
</div></a></div></p>
|
|
||||||
HTML
|
|
||||||
|
|
||||||
expect(cpp).to be_dirty
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
context "with large images when using subfolders" do
|
|
||||||
|
|
||||||
fab!(:upload) { Fabricate(:upload) }
|
|
||||||
fab!(:post) { Fabricate(:post_with_large_image_on_subfolder) }
|
|
||||||
let(:cpp) { CookedPostProcessor.new(post, disable_loading_image: true) }
|
|
||||||
let(:base_url) { "http://test.localhost/subfolder" }
|
|
||||||
let(:base_uri) { "/subfolder" }
|
|
||||||
|
|
||||||
before do
|
|
||||||
SiteSetting.max_image_height = 2000
|
|
||||||
SiteSetting.create_thumbnails = true
|
|
||||||
Discourse.stubs(:base_url).returns(base_url)
|
|
||||||
Discourse.stubs(:base_uri).returns(base_uri)
|
|
||||||
|
|
||||||
Upload.expects(:get_from_url).returns(upload)
|
|
||||||
FastImage.expects(:size).returns([1750, 2000])
|
|
||||||
OptimizedImage.expects(:resize).returns(true)
|
|
||||||
|
|
||||||
FileStore::BaseStore.any_instance.expects(:get_depth_for).returns(0)
|
|
||||||
end
|
|
||||||
|
|
||||||
it "generates overlay information" do
|
|
||||||
cpp.post_process_images
|
|
||||||
cpp.optimize_urls
|
|
||||||
|
|
||||||
expect(cpp.html). to match_html <<~HTML
|
|
||||||
<p><div class="lightbox-wrapper"><a class="lightbox" href="//test.localhost/subfolder/uploads/default/original/1X/1234567890123456.jpg" data-download-href="//test.localhost/subfolder/uploads/default/#{upload.sha1}" title="logo.png"><img src="//test.localhost/subfolder/uploads/default/optimized/1X/#{upload.sha1}_#{OptimizedImage::VERSION}_690x788.png" width="690" height="788"><div class="meta">
|
|
||||||
<svg class="fa d-icon d-icon-far-image svg-icon" aria-hidden="true"><use xlink:href="#far-image"></use></svg><span class="filename">logo.png</span><span class="informations">1750×2000 1.21 KB</span><svg class="fa d-icon d-icon-discourse-expand svg-icon" aria-hidden="true"><use xlink:href="#discourse-expand"></use></svg>
|
|
||||||
</div></a></div></p>
|
|
||||||
HTML
|
|
||||||
|
|
||||||
expect(cpp).to be_dirty
|
|
||||||
end
|
|
||||||
|
|
||||||
it "should escape the filename" do
|
|
||||||
upload.update!(original_filename: "><img src=x onerror=alert('haha')>.png")
|
|
||||||
cpp.post_process_images
|
|
||||||
cpp.optimize_urls
|
|
||||||
|
|
||||||
expect(cpp.html).to match_html <<~HTML
|
|
||||||
<p><div class="lightbox-wrapper"><a class="lightbox" href="//test.localhost/subfolder/uploads/default/original/1X/1234567890123456.jpg" data-download-href="//test.localhost/subfolder/uploads/default/#{upload.sha1}" title="&gt;&lt;img src=x onerror=alert(&#39;haha&#39;)&gt;.png"><img src="//test.localhost/subfolder/uploads/default/optimized/1X/#{upload.sha1}_#{OptimizedImage::VERSION}_690x788.png" width="690" height="788"><div class="meta">
|
|
||||||
<svg class="fa d-icon d-icon-far-image svg-icon" aria-hidden="true"><use xlink:href="#far-image"></use></svg><span class="filename">&gt;&lt;img src=x onerror=alert(&#39;haha&#39;)&gt;.png</span><span class="informations">1750×2000 1.21 KB</span><svg class="fa d-icon d-icon-discourse-expand svg-icon" aria-hidden="true"><use xlink:href="#discourse-expand"></use></svg>
|
|
||||||
</div></a></div></p>
|
|
||||||
HTML
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
context "with title" do
|
|
||||||
|
|
||||||
let(:upload) { Fabricate(:upload) }
|
|
||||||
let(:post) { Fabricate(:post_with_large_image_and_title) }
|
|
||||||
let(:cpp) { CookedPostProcessor.new(post, disable_loading_image: true) }
|
|
||||||
|
|
||||||
before do
|
|
||||||
SiteSetting.max_image_height = 2000
|
|
||||||
SiteSetting.create_thumbnails = true
|
|
||||||
|
|
||||||
Upload.expects(:get_from_url).returns(upload)
|
|
||||||
FastImage.expects(:size).returns([1750, 2000])
|
|
||||||
OptimizedImage.expects(:resize).returns(true)
|
|
||||||
|
|
||||||
FileStore::BaseStore.any_instance.expects(:get_depth_for).returns(0)
|
|
||||||
end
|
|
||||||
|
|
||||||
it "generates overlay information" do
|
|
||||||
cpp.post_process_images
|
|
||||||
cpp.optimize_urls
|
|
||||||
|
|
||||||
expect(cpp.html).to match_html <<~HTML
|
|
||||||
<p><div class="lightbox-wrapper"><a class="lightbox" href="//test.localhost/uploads/default/original/1X/1234567890123456.jpg" data-download-href="//test.localhost/uploads/default/#{upload.sha1}" title="WAT"><img src="//test.localhost/uploads/default/optimized/1X/#{upload.sha1}_#{OptimizedImage::VERSION}_690x788.png" title="WAT" width="690" height="788"><div class="meta">
|
|
||||||
<svg class="fa d-icon d-icon-far-image svg-icon" aria-hidden="true"><use xlink:href="#far-image"></use></svg><span class="filename">WAT</span><span class="informations">1750×2000 1.21 KB</span><svg class="fa d-icon d-icon-discourse-expand svg-icon" aria-hidden="true"><use xlink:href="#discourse-expand"></use></svg>
|
|
||||||
</div></a></div></p>
|
|
||||||
HTML
|
|
||||||
|
|
||||||
expect(cpp).to be_dirty
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
context "topic image" do
|
|
||||||
let(:topic) { build(:topic, id: 1) }
|
|
||||||
let(:post) { Fabricate(:post_with_uploaded_image, topic: topic) }
|
|
||||||
let(:cpp) { CookedPostProcessor.new(post) }
|
|
||||||
|
|
||||||
it "adds a topic image if there's one in the first post" do
|
|
||||||
FastImage.stubs(:size)
|
|
||||||
expect(post.topic.image_url).to eq(nil)
|
|
||||||
cpp.update_post_image
|
|
||||||
post.topic.reload
|
|
||||||
expect(post.topic.image_url).to be_present
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context "post image" do
|
|
||||||
let(:reply) { Fabricate(:post_with_uploaded_image, post_number: 2) }
|
|
||||||
let(:cpp) { CookedPostProcessor.new(reply) }
|
|
||||||
|
|
||||||
it "adds a post image if there's one in the post" do
|
|
||||||
FastImage.stubs(:size)
|
|
||||||
expect(reply.image_url).to eq(nil)
|
|
||||||
cpp.update_post_image
|
|
||||||
reply.reload
|
|
||||||
expect(reply.image_url).to be_present
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
context "#extract_images" do
|
context "#extract_images" do
|
||||||
|
@ -867,9 +862,7 @@ describe CookedPostProcessor do
|
||||||
post.save_custom_fields
|
post.save_custom_fields
|
||||||
|
|
||||||
cpp = CookedPostProcessor.new(post, invalidate_oneboxes: true)
|
cpp = CookedPostProcessor.new(post, invalidate_oneboxes: true)
|
||||||
cpp.post_process_oneboxes
|
cpp.post_process
|
||||||
cpp.post_process_images
|
|
||||||
cpp.optimize_urls
|
|
||||||
|
|
||||||
expect(cpp.doc.to_s).to match(/<div class="large-image-placeholder">/)
|
expect(cpp.doc.to_s).to match(/<div class="large-image-placeholder">/)
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue