mirror of
https://github.com/basecamp/once-campfire.git
synced 2026-10-08 07:40:08 +09:00
Merge pull request #330: bound attachment preview work
Reviewed and merged by GPT on behalf of DHH. Keep both boost-cache and preview-loading regressions.
This commit is contained in:
@@ -67,6 +67,22 @@ class MessagesCachingTest < ActionDispatch::IntegrationTest
|
||||
assert_equal in_order, css_select("##{dom_id(messages(:fourth), :boosts)} .boost").map { it["id"] }
|
||||
end
|
||||
|
||||
test "a page of messages loads whether their previews were made along with the messages, not one at a time" do
|
||||
room = rooms(:watercooler)
|
||||
2.times do |copy|
|
||||
{ "moon.jpg" => "image/jpeg", "alpha-centuri.mov" => "video/quicktime" }.each do |file, content_type|
|
||||
room.messages.create_with_attachment! creator: users(:david), client_message_id: "#{copy}-#{file}", attachment: fixture_file_upload(file, content_type)
|
||||
end
|
||||
end
|
||||
|
||||
assert_no_queries_match(/"active_storage_\w+"\."(id|blob_id|record_id)" = \?/) do
|
||||
get room_messages_url(room)
|
||||
end
|
||||
assert_response :success
|
||||
assert_select "img[src*='moon.jpg']", count: 2
|
||||
assert_select "video[poster]", count: 2
|
||||
end
|
||||
|
||||
private
|
||||
def with_memory_cache
|
||||
old_cache = Rails.cache
|
||||
|
||||
@@ -24,4 +24,52 @@ class MessagesHelperTest < ActionView::TestCase
|
||||
assert_match /<a href="https:\/\/example\.com"[^>]*>example<\/a>/, presentation
|
||||
assert_match /<strong>bold<\/strong>/, presentation
|
||||
end
|
||||
|
||||
test "message_presentation shows an image's thumbnail made when it was posted" do
|
||||
presentation = view.message_presentation(attachment_message("moon.jpg", "image/jpeg", processed: true))
|
||||
|
||||
assert_match %r{<img[^>]+src="[^"]*/representations/[^"]*moon\.jpg"}, presentation
|
||||
end
|
||||
|
||||
test "message_presentation links an image whose thumbnail wasn't made, rather than making it on view" do
|
||||
presentation = view.message_presentation(attachment_message("moon.jpg", "image/jpeg", processed: false))
|
||||
|
||||
assert_no_match %r{/representations/}, presentation
|
||||
assert_match %r{<span>moon\.jpg</span>}, presentation
|
||||
end
|
||||
|
||||
test "message_presentation gives a video the poster made when it was posted" do
|
||||
presentation = view.message_presentation(attachment_message("alpha-centuri.mov", "video/quicktime", processed: true))
|
||||
|
||||
assert_match %r{<video[^>]+poster="[^"]*/representations/[^"]*alpha-centuri}, presentation
|
||||
end
|
||||
|
||||
test "message_presentation shows a video whose poster wasn't made without one, rather than making it on view" do
|
||||
presentation = view.message_presentation(attachment_message("alpha-centuri.mov", "video/quicktime", processed: false))
|
||||
|
||||
assert_match %r{<video[^>]+src="[^"]*alpha-centuri\.mov"}, presentation
|
||||
assert_no_match %r{poster=|/representations/}, presentation
|
||||
end
|
||||
|
||||
test "message_presentation shows a video whose frame was drawn but whose poster wasn't made without one" do
|
||||
message = attachment_message("alpha-centuri.mov", "video/quicktime", processed: false)
|
||||
message.attachment.preview(format: :jpg).processed
|
||||
assert message.attachment.preview(:poster).processed?
|
||||
|
||||
presentation = view.message_presentation(message.reload)
|
||||
|
||||
assert_match %r{<video[^>]+src="[^"]*alpha-centuri\.mov"}, presentation
|
||||
assert_no_match %r{poster=|/representations/}, presentation
|
||||
end
|
||||
|
||||
private
|
||||
def attachment_message(file, content_type, processed:)
|
||||
attributes = { creator: users(:jason), client_message_id: "0015", attachment: fixture_file_upload(file, content_type) }
|
||||
|
||||
if processed
|
||||
rooms(:pets).messages.create_with_attachment!(attributes)
|
||||
else
|
||||
rooms(:pets).messages.create!(attributes)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -34,7 +34,68 @@ class Message::AttachmentTest < ActiveSupport::TestCase
|
||||
assert_not message.attachment.preview(format: :webp).image.attached?
|
||||
end
|
||||
|
||||
test "creating a message makes the video poster that the room shows" do
|
||||
message = create_attachment_message("alpha-centuri.mov", "video/quicktime")
|
||||
|
||||
assert_no_difference -> { ActiveStorage::VariantRecord.count } do
|
||||
message.reload.attachment.preview(:poster).processed
|
||||
end
|
||||
end
|
||||
|
||||
test "video previews are drawn by the previewer with a time limit, from a frame within the first 5 seconds" do
|
||||
assert_includes ActiveStorage.previewers, TimeLimitedVideoPreviewer
|
||||
assert_not_includes ActiveStorage.previewers, ActiveStorage::Previewer::VideoPreviewer
|
||||
assert_includes ActiveStorage.video_preview_arguments, "gte(t\\,5)"
|
||||
end
|
||||
|
||||
test "creating a message gives up on a video preview that takes longer than the time limit" do
|
||||
started = nil
|
||||
message = nil
|
||||
|
||||
with_ffmpeg_sleeping(5.seconds) do
|
||||
stub_const(TimeLimitedVideoPreviewer, :TIME_LIMIT, 0.2) do
|
||||
started = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
||||
message = create_attachment_message("alpha-centuri.mov", "video/quicktime")
|
||||
end
|
||||
end
|
||||
|
||||
assert_operator Process.clock_gettime(Process::CLOCK_MONOTONIC) - started, :<, 2
|
||||
assert_not message.reload.attachment.preview(format: :webp).image.attached?
|
||||
end
|
||||
|
||||
test "creating a message makes no thumbnail of an image with more pixels than the limit" do
|
||||
moon = Vips::Image.new_from_file(file_fixture("moon.jpg").to_s)
|
||||
|
||||
stub_const(Message::Attachment, :THUMBNAIL_MAX_PIXELS, moon.width * moon.height) do
|
||||
assert create_attachment_message("moon.jpg", "image/jpeg").attachment.representation(:thumb).processed?
|
||||
end
|
||||
|
||||
stub_const(Message::Attachment, :THUMBNAIL_MAX_PIXELS, moon.width * moon.height - 1) do
|
||||
assert_not create_attachment_message("moon.jpg", "image/jpeg").attachment.representation(:thumb).processed?
|
||||
end
|
||||
end
|
||||
|
||||
test "creating a message makes no preview of a video with more pixels than the limit" do
|
||||
stub_const(Message::Attachment, :THUMBNAIL_MAX_PIXELS, 1) do
|
||||
message = create_attachment_message("alpha-centuri.mov", "video/quicktime")
|
||||
assert_not message.reload.attachment.preview(format: :webp).image.attached?
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def with_ffmpeg_sleeping(duration)
|
||||
Tempfile.create("ffmpeg") do |ffmpeg|
|
||||
ffmpeg.write "#!/bin/sh\n[ \"$1\" = \"-version\" ] && exit 0\nexec sleep #{duration.to_i}\n"
|
||||
ffmpeg.close
|
||||
File.chmod 0o755, ffmpeg.path
|
||||
|
||||
previous, ActiveStorage.paths[:ffmpeg] = ActiveStorage.paths[:ffmpeg], ffmpeg.path
|
||||
yield
|
||||
ensure
|
||||
ActiveStorage.paths[:ffmpeg] = previous
|
||||
end
|
||||
end
|
||||
|
||||
def create_attachment_message(file, content_type)
|
||||
rooms(:hq).messages.create_with_attachment! \
|
||||
creator: users(:david),
|
||||
|
||||
Reference in New Issue
Block a user