Fixes #3093 - Inline images are cut during forward and reply (quotation)
This commit is contained in:
parent
9a5be2ae00
commit
806cd7def6
5 changed files with 76 additions and 7 deletions
3
Gemfile
3
Gemfile
|
@ -203,6 +203,9 @@ group :development, :test do
|
||||||
|
|
||||||
# handle deprecations in core and addons
|
# handle deprecations in core and addons
|
||||||
gem 'deprecation_toolkit'
|
gem 'deprecation_toolkit'
|
||||||
|
|
||||||
|
# image comparison in tests
|
||||||
|
gem 'chunky_png'
|
||||||
end
|
end
|
||||||
|
|
||||||
# Want to extend Zammad with additional gems?
|
# Want to extend Zammad with additional gems?
|
||||||
|
|
|
@ -132,6 +132,7 @@ GEM
|
||||||
xpath (~> 3.2)
|
xpath (~> 3.2)
|
||||||
childprocess (1.0.1)
|
childprocess (1.0.1)
|
||||||
rake (< 13.0)
|
rake (< 13.0)
|
||||||
|
chunky_png (1.3.12)
|
||||||
clavius (1.0.4)
|
clavius (1.0.4)
|
||||||
clearbit (0.2.8)
|
clearbit (0.2.8)
|
||||||
nestful (~> 1.1.0)
|
nestful (~> 1.1.0)
|
||||||
|
@ -585,6 +586,7 @@ DEPENDENCIES
|
||||||
browser
|
browser
|
||||||
byebug
|
byebug
|
||||||
capybara
|
capybara
|
||||||
|
chunky_png
|
||||||
clearbit
|
clearbit
|
||||||
coffee-rails
|
coffee-rails
|
||||||
coffee-script-source
|
coffee-script-source
|
||||||
|
|
|
@ -1222,7 +1222,7 @@ class App.Utils
|
||||||
canvas.width = img.width
|
canvas.width = img.width
|
||||||
canvas.height = img.height
|
canvas.height = img.height
|
||||||
ctx = canvas.getContext('2d')
|
ctx = canvas.getContext('2d')
|
||||||
ctx.drawImage(img, 0, 0)
|
ctx.drawImage(img, 0, 0, img.width, img.height)
|
||||||
try
|
try
|
||||||
data = canvas.toDataURL('image/png')
|
data = canvas.toDataURL('image/png')
|
||||||
params.success(img, data) if params.success
|
params.success(img, data) if params.success
|
||||||
|
@ -1242,12 +1242,11 @@ class App.Utils
|
||||||
return if !src? or src.match(/^(data|cid):/i)
|
return if !src? or src.match(/^(data|cid):/i)
|
||||||
App.Utils._htmlImage2DataUrlAsync(@,
|
App.Utils._htmlImage2DataUrlAsync(@,
|
||||||
success: (img, data) ->
|
success: (img, data) ->
|
||||||
$img = $(img)
|
element.attr('src', data)
|
||||||
$img.attr('src', data)
|
element.css('max-width','100%')
|
||||||
$img.css('max-width','100%')
|
params.success(element, data) if params.success
|
||||||
params.success(img, data) if params.success
|
|
||||||
fail: (img) ->
|
fail: (img) ->
|
||||||
img.remove()
|
element.remove()
|
||||||
params.fail(img) if params.fail
|
params.fail(img) if params.fail
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -1283,7 +1282,7 @@ class App.Utils
|
||||||
imageCache = new Image()
|
imageCache = new Image()
|
||||||
imageCache.crossOrigin = 'anonymous'
|
imageCache.crossOrigin = 'anonymous'
|
||||||
imageCache.onload = ->
|
imageCache.onload = ->
|
||||||
App.Utils._htmlImage2DataUrl(originalImage, params)
|
App.Utils._htmlImage2DataUrl(imageCache, params)
|
||||||
imageCache.onerror = ->
|
imageCache.onerror = ->
|
||||||
App.Log.notice('Utils', "Unable to load image from #{originalImage.src}")
|
App.Log.notice('Utils', "Unable to load image from #{originalImage.src}")
|
||||||
params.fail(originalImage) if params.fail
|
params.fail(originalImage) if params.fail
|
||||||
|
|
BIN
spec/fixtures/image/squares.png
vendored
Normal file
BIN
spec/fixtures/image/squares.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 22 KiB |
|
@ -812,4 +812,69 @@ RSpec.describe 'Ticket zoom', type: :system do
|
||||||
include_examples 'verify linking'
|
include_examples 'verify linking'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe 'forwarding article with an image' do
|
||||||
|
let(:ticket_article_body) do
|
||||||
|
filename = 'squares.png'
|
||||||
|
file = File.binread(Rails.root.join("spec/fixtures/image/#{filename}"))
|
||||||
|
ext = File.extname(filename)[1...]
|
||||||
|
base64 = Base64.encode64(file).delete("\n")
|
||||||
|
|
||||||
|
"<img style='width: 1004px; max-width: 100%;' src=\\\"data:image/#{ext};base64,#{base64}\\\"><br>"
|
||||||
|
end
|
||||||
|
|
||||||
|
def current_ticket
|
||||||
|
Ticket.find current_url.split('/').last
|
||||||
|
end
|
||||||
|
|
||||||
|
def create_ticket
|
||||||
|
visit '#ticket/create'
|
||||||
|
|
||||||
|
within :active_content do
|
||||||
|
find('[data-type=email-out]').click
|
||||||
|
|
||||||
|
find('[name=title]').fill_in with: 'Title'
|
||||||
|
find('[name=customer_id_completion]').fill_in with: 'customer@example.com'
|
||||||
|
find('[name=group_id]').select 'Users'
|
||||||
|
find(:richtext).execute_script "this.innerHTML = \"#{ticket_article_body}\""
|
||||||
|
find('.js-submit').click
|
||||||
|
end
|
||||||
|
|
||||||
|
await_empty_ajax_queue
|
||||||
|
end
|
||||||
|
|
||||||
|
def forward
|
||||||
|
within :active_content do
|
||||||
|
click '.js-ArticleAction[data-type=emailForward]'
|
||||||
|
fill_in 'To', with: 'customer@example.com'
|
||||||
|
find('.js-submit').click
|
||||||
|
end
|
||||||
|
|
||||||
|
await_empty_ajax_queue
|
||||||
|
end
|
||||||
|
|
||||||
|
def images_identical?(image_a, image_b)
|
||||||
|
return false if image_a.height != image_b.height
|
||||||
|
return false if image_a.width != image_b.width
|
||||||
|
|
||||||
|
image_a.height.times do |y|
|
||||||
|
image_a.row(y).each_with_index do |pixel, x|
|
||||||
|
return false unless pixel == image_b[x, y]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'keeps image intact' do
|
||||||
|
create_ticket
|
||||||
|
forward
|
||||||
|
|
||||||
|
images = current_ticket.articles.map do |article|
|
||||||
|
ChunkyPNG::Image.from_string article.attachments.first.content
|
||||||
|
end
|
||||||
|
|
||||||
|
expect(images_identical?(images.first, images.second)).to be(true)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue