summaryrefslogtreecommitdiff
path: root/spec/lib/gitlab/sanitizers/exif_spec.rb
diff options
context:
space:
mode:
Diffstat (limited to 'spec/lib/gitlab/sanitizers/exif_spec.rb')
-rw-r--r--spec/lib/gitlab/sanitizers/exif_spec.rb120
1 files changed, 120 insertions, 0 deletions
diff --git a/spec/lib/gitlab/sanitizers/exif_spec.rb b/spec/lib/gitlab/sanitizers/exif_spec.rb
new file mode 100644
index 00000000000..bd5f330c7a1
--- /dev/null
+++ b/spec/lib/gitlab/sanitizers/exif_spec.rb
@@ -0,0 +1,120 @@
+require 'spec_helper'
+
+describe Gitlab::Sanitizers::Exif do
+ let(:sanitizer) { described_class.new }
+
+ describe '#batch_clean' do
+ context 'with image uploads' do
+ let!(:uploads) { create_list(:upload, 3, :with_file, :issuable_upload) }
+
+ it 'processes all uploads if range ID is not set' do
+ expect(sanitizer).to receive(:clean).exactly(3).times
+
+ sanitizer.batch_clean
+ end
+
+ it 'processes only uploads in the selected range' do
+ expect(sanitizer).to receive(:clean).once
+
+ sanitizer.batch_clean(start_id: uploads[1].id, stop_id: uploads[1].id)
+ end
+
+ it 'pauses if sleep_time is set' do
+ expect(sanitizer).to receive(:sleep).exactly(3).times.with(1.second)
+ expect(sanitizer).to receive(:clean).exactly(3).times
+
+ sanitizer.batch_clean(sleep_time: 1)
+ end
+ end
+
+ it 'filters only jpg/tiff images' do
+ create(:upload, path: 'filename.jpg')
+ create(:upload, path: 'filename.jpeg')
+ create(:upload, path: 'filename.JPG')
+ create(:upload, path: 'filename.tiff')
+ create(:upload, path: 'filename.TIFF')
+ create(:upload, path: 'filename.png')
+ create(:upload, path: 'filename.txt')
+
+ expect(sanitizer).to receive(:clean).exactly(5).times
+ sanitizer.batch_clean
+ end
+ end
+
+ describe '#clean' do
+ let(:uploader) { create(:upload, :with_file, :issuable_upload).build_uploader }
+
+ context "no dry run" do
+ it "removes exif from the image" do
+ uploader.store!(fixture_file_upload('spec/fixtures/rails_sample.jpg'))
+
+ original_upload = uploader.upload
+ expected_args = ["exiftool", "-all=", "-tagsFromFile", "@", *Gitlab::Sanitizers::Exif::EXCLUDE_PARAMS, "--IPTC:all", "--XMP-iptcExt:all", kind_of(String)]
+
+ expect(sanitizer).to receive(:extra_tags).and_return(["", 0])
+ expect(sanitizer).to receive(:exec_remove_exif!).once.and_call_original
+ expect(uploader).to receive(:store!).and_call_original
+ expect(Gitlab::Popen).to receive(:popen).with(expected_args) do |args|
+ File.write("#{args.last}_original", "foo") if args.last.start_with?(Dir.tmpdir)
+
+ [expected_args, 0]
+ end
+
+ sanitizer.clean(uploader, dry_run: false)
+
+ expect(uploader.upload.id).not_to eq(original_upload.id)
+ expect(uploader.upload.path).to eq(original_upload.path)
+ end
+
+ it "ignores image without exif" do
+ expected_args = ["exiftool", "-all", "-j", "-sort", "--IPTC:all", "--XMP-iptcExt:all", kind_of(String)]
+
+ expect(Gitlab::Popen).to receive(:popen).with(expected_args).and_return(["[{}]", 0])
+ expect(sanitizer).not_to receive(:exec_remove_exif!)
+ expect(uploader).not_to receive(:store!)
+
+ sanitizer.clean(uploader, dry_run: false)
+ end
+
+ it "raises an error if the exiftool fails with an error" do
+ expect(Gitlab::Popen).to receive(:popen).and_return(["error", 1])
+
+ expect { sanitizer.clean(uploader, dry_run: false) }.to raise_exception(RuntimeError, "failed to get exif tags: error")
+ end
+ end
+
+ context "dry run" do
+ it "doesn't change the image" do
+ expect(sanitizer).to receive(:extra_tags).and_return({ 'foo' => 'bar' })
+ expect(sanitizer).not_to receive(:exec_remove_exif!)
+ expect(uploader).not_to receive(:store!)
+
+ sanitizer.clean(uploader, dry_run: true)
+ end
+ end
+ end
+
+ describe "#extra_tags" do
+ it "returns a list of keys for exif file" do
+ tags = '[{
+ "DigitalSourceType": "some source",
+ "ImageHeight": 654
+ }]'
+
+ expect(Gitlab::Popen).to receive(:popen).and_return([tags, 0])
+
+ expect(sanitizer.extra_tags('filename')).not_to be_empty
+ end
+
+ it "returns an empty list for file with only whitelisted and ignored tags" do
+ tags = '[{
+ "ImageHeight": 654,
+ "Megapixels": 0.641
+ }]'
+
+ expect(Gitlab::Popen).to receive(:popen).and_return([tags, 0])
+
+ expect(sanitizer.extra_tags('some file')).to be_empty
+ end
+ end
+end