diff --git a/Gemfile b/Gemfile index db01175f8..4b71c7913 100644 --- a/Gemfile +++ b/Gemfile @@ -203,6 +203,9 @@ group :development, :test do # handle deprecations in core and addons gem 'deprecation_toolkit' + + # image comparison in tests + gem 'chunky_png' end # Want to extend Zammad with additional gems? diff --git a/Gemfile.lock b/Gemfile.lock index d615376bf..86315cd9f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -132,6 +132,7 @@ GEM xpath (~> 3.2) childprocess (1.0.1) rake (< 13.0) + chunky_png (1.3.12) clavius (1.0.4) clearbit (0.2.8) nestful (~> 1.1.0) @@ -585,6 +586,7 @@ DEPENDENCIES browser byebug capybara + chunky_png clearbit coffee-rails coffee-script-source diff --git a/app/assets/javascripts/app/lib/app_post/utils.coffee b/app/assets/javascripts/app/lib/app_post/utils.coffee index 632cce11f..7df426a16 100644 --- a/app/assets/javascripts/app/lib/app_post/utils.coffee +++ b/app/assets/javascripts/app/lib/app_post/utils.coffee @@ -1222,7 +1222,7 @@ class App.Utils canvas.width = img.width canvas.height = img.height ctx = canvas.getContext('2d') - ctx.drawImage(img, 0, 0) + ctx.drawImage(img, 0, 0, img.width, img.height) try data = canvas.toDataURL('image/png') params.success(img, data) if params.success @@ -1242,12 +1242,11 @@ class App.Utils return if !src? or src.match(/^(data|cid):/i) App.Utils._htmlImage2DataUrlAsync(@, success: (img, data) -> - $img = $(img) - $img.attr('src', data) - $img.css('max-width','100%') - params.success(img, data) if params.success + element.attr('src', data) + element.css('max-width','100%') + params.success(element, data) if params.success fail: (img) -> - img.remove() + element.remove() params.fail(img) if params.fail ) ) @@ -1283,7 +1282,7 @@ class App.Utils imageCache = new Image() imageCache.crossOrigin = 'anonymous' imageCache.onload = -> - App.Utils._htmlImage2DataUrl(originalImage, params) + App.Utils._htmlImage2DataUrl(imageCache, params) imageCache.onerror = -> App.Log.notice('Utils', "Unable to load image from #{originalImage.src}") params.fail(originalImage) if params.fail diff --git a/spec/fixtures/image/squares.png b/spec/fixtures/image/squares.png new file mode 100644 index 000000000..a6e6ba992 Binary files /dev/null and b/spec/fixtures/image/squares.png differ diff --git a/spec/system/ticket/zoom_spec.rb b/spec/system/ticket/zoom_spec.rb index 319ea0f05..d237e644e 100644 --- a/spec/system/ticket/zoom_spec.rb +++ b/spec/system/ticket/zoom_spec.rb @@ -812,4 +812,69 @@ RSpec.describe 'Ticket zoom', type: :system do include_examples 'verify linking' 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") + + "
" + 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