inline_images_spec.rb 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. require 'rails_helper'
  3. RSpec.describe HtmlSanitizer::Scrubber::InlineImages do
  4. let(:scrubber) { described_class.new }
  5. let(:base64) { 'data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/...' }
  6. describe('#scrubber') do
  7. subject(:actual) { fragment.scrub!(scrubber).to_html }
  8. let(:fragment) { Loofah.fragment(input) }
  9. context 'when matching image' do
  10. let(:input) { '<img src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/...">' }
  11. let(:target) { %r{<img src="cid:.+?">} }
  12. it { is_expected.to match target }
  13. it 'adds attachment to scrubber' do
  14. actual
  15. expect(scrubber.attachments_inline).to match_array(include(filename: 'image1.jpeg'))
  16. end
  17. context 'when uploaded image is handled' do
  18. let(:input) { "<img src='/api/v1/attachments/#{Store.last.id}'>" }
  19. let(:target) { %r{<img src="cid:.+?">} }
  20. before do
  21. form_id = SecureRandom.uuid
  22. file_name = 'file1.png'
  23. file_type = 'image/png'
  24. file_content = Base64.strict_encode64('file1')
  25. UploadCache.new(form_id).tap do |cache|
  26. cache.add(
  27. data: file_content,
  28. filename: file_name,
  29. preferences: { 'Content-Type' => file_type },
  30. created_by_id: 1,
  31. )
  32. end
  33. end
  34. it { is_expected.to match target }
  35. it 'adds attachment to scrubber' do
  36. actual
  37. expect(scrubber.attachments_inline).to match_array(include(filename: 'file1.png'))
  38. end
  39. end
  40. context 'when upload failed' do
  41. let(:input) { '<img src="blob:/api/v1/attachments/111">' }
  42. let(:target) { '' }
  43. it { is_expected.to match target }
  44. end
  45. end
  46. context 'when not matching image' do
  47. let(:input) { '<img src="/image1.jpg">' }
  48. let(:target) { '<img src="/image1.jpg">' }
  49. it { is_expected.to eq target }
  50. it 'adds no attachments to scrubber' do
  51. actual
  52. expect(scrubber.attachments_inline).to be_blank
  53. end
  54. end
  55. end
  56. describe '#inline_image_data' do
  57. it 'truthy when image' do
  58. input = base64
  59. expect(scrubber.send(:inline_image_data, input)).to be_truthy
  60. end
  61. it 'falsey when non-jpeg/png' do
  62. input = 'data:image/gif;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/...'
  63. expect(scrubber.send(:inline_image_data, input)).to be_falsey
  64. end
  65. it 'falsey when URL' do
  66. input = '/image.jpeg'
  67. expect(scrubber.send(:inline_image_data, input)).to be_falsey
  68. end
  69. end
  70. describe '#process_inline_image' do
  71. it 'adds image to attachments' do
  72. scrubber.send(:process_inline_image, {}, base64)
  73. first_attachment = scrubber.send(:attachments_inline).first
  74. expect(first_attachment).to include(filename: 'image1.jpeg')
  75. end
  76. it 'adds multiple numbered images to attachments' do
  77. 2.times { scrubber.send(:process_inline_image, {}, base64) }
  78. filenames = scrubber.send(:attachments_inline).pluck(:filename)
  79. expect(filenames).to eq %w[image1.jpeg image2.jpeg]
  80. end
  81. it 'sets src to cid' do
  82. node = {}
  83. allow(scrubber).to receive(:generate_cid).and_return('identifier')
  84. scrubber.send(:process_inline_image, node, base64)
  85. expect(node).to include('src' => 'cid:identifier')
  86. end
  87. end
  88. describe '#generate_cid' do
  89. it 'generates cid' do
  90. allow(scrubber).to receive(:prefix).and_return(:prefix)
  91. expect(scrubber.send(:generate_cid)).to start_with('prefix.').and(end_with('zammad.example.com'))
  92. end
  93. end
  94. describe '#parse_inline_image' do
  95. let(:expected) do
  96. include(
  97. data: be_present,
  98. filename: 'image1.jpeg',
  99. preferences: {
  100. 'Content-Type' => 'image/jpeg',
  101. 'Mime-Type' => 'image/jpeg',
  102. 'Content-ID' => :identifier,
  103. 'Content-Disposition' => 'inline',
  104. }
  105. )
  106. end
  107. it 'returns hash' do
  108. expect(scrubber.send(:parse_inline_image, base64, :identifier)).to expected
  109. end
  110. end
  111. end