Some imagemagick-versions (I tested Ubuntu 22.04 and debian bullseye) always loose exif data when converting from jpg to webp. So this made our CI fail now, but even if it wasn't failing before, some pods always had and have versions which might loose the information anyway. So having a setting to keep exif information is kinda pointless, if we can't guarantee that the information isn't lost. Also, diaspora isn't a photo sharing platform and we don't display exif information anywhere, so I think we should just always strip exif data (which was already the default before), as we don't need them.
270 lines
7.8 KiB
Ruby
270 lines
7.8 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
# Copyright (c) 2010-2011, Diaspora Inc. This file is
|
|
# licensed under the Affero General Public License version 3 or later. See
|
|
# the COPYRIGHT file.
|
|
|
|
def with_carrierwave_processing(&block)
|
|
UnprocessedImage.enable_processing = true
|
|
val = yield
|
|
UnprocessedImage.enable_processing = false
|
|
val
|
|
end
|
|
|
|
describe Photo, :type => :model do
|
|
before do
|
|
@user = alice
|
|
@aspect = @user.aspects.first
|
|
|
|
@fixture_filename = 'button.png'
|
|
|
|
@fixture_name = File.join(File.dirname(__FILE__), '..', 'fixtures', @fixture_filename)
|
|
@fail_fixture_name = File.join(File.dirname(__FILE__), '..', 'fixtures', 'msg.xml')
|
|
|
|
@photo = @user.build_post(:photo, user_file: File.open(@fixture_name), to: @aspect.id)
|
|
@photo2 = @user.build_post(:photo, user_file: File.open(@fixture_name), to: @aspect.id)
|
|
@saved_photo = @user.build_post(:photo, user_file: File.open(@fixture_name), to: @aspect.id)
|
|
@saved_photo.save
|
|
end
|
|
|
|
describe 'after_create' do
|
|
it 'calls #queue_processing_job' do
|
|
expect(@photo).to receive(:queue_processing_job)
|
|
|
|
@photo.save!
|
|
end
|
|
end
|
|
|
|
it 'has a random string key' do
|
|
expect(@photo2.random_string).not_to be nil
|
|
end
|
|
|
|
describe '#diaspora_initialize' do
|
|
before do
|
|
@image = File.open(@fixture_name)
|
|
@photo = Photo.diaspora_initialize(author: @user.person, user_file: @image)
|
|
end
|
|
|
|
it 'sets the persons diaspora handle' do
|
|
expect(@photo.diaspora_handle).to eq(@user.person.diaspora_handle)
|
|
end
|
|
|
|
it 'sets the random prefix' do
|
|
photo_double = double.as_null_object
|
|
expect(photo_double).to receive(:random_string=)
|
|
allow(Photo).to receive(:new).and_return(photo_double)
|
|
|
|
Photo.diaspora_initialize(
|
|
:author => @user.person, :user_file => @image)
|
|
end
|
|
|
|
context "with user file" do
|
|
it 'builds the photo without saving' do
|
|
expect(@photo.created_at.nil?).to be true
|
|
expect(@photo.unprocessed_image.read.nil?).to be false
|
|
end
|
|
end
|
|
|
|
context "with a url" do
|
|
it 'saves the photo' do
|
|
url = "https://service.com/user/profile_image"
|
|
|
|
photo_double = double.as_null_object
|
|
expect(photo_double).to receive(:remote_unprocessed_image_url=).with(url)
|
|
allow(Photo).to receive(:new).and_return(photo_double)
|
|
|
|
Photo.diaspora_initialize(
|
|
:author => @user.person, :image_url => url)
|
|
end
|
|
end
|
|
end
|
|
|
|
describe '#update_remote_path' do
|
|
before do
|
|
image = File.open(@fixture_name)
|
|
@photo = Photo.diaspora_initialize(
|
|
:author => @user.person, :user_file => image)
|
|
@photo.processed_image.store!(@photo.unprocessed_image)
|
|
@photo.save!
|
|
end
|
|
it 'sets a remote url' do
|
|
@photo.update_remote_path
|
|
|
|
expect(@photo.remote_photo_path).to include("http")
|
|
expect(@photo.remote_photo_name).to include(".webp")
|
|
end
|
|
end
|
|
|
|
it 'should save a photo' do
|
|
@photo.unprocessed_image.store! File.open(@fixture_name)
|
|
expect(@photo.save).to eq(true)
|
|
|
|
binary = @photo.unprocessed_image.read.force_encoding('BINARY')
|
|
fixture_binary = File.read(@fixture_name).force_encoding('BINARY')
|
|
|
|
expect(binary).to eq(fixture_binary)
|
|
end
|
|
|
|
context 'with a saved photo' do
|
|
before do
|
|
with_carrierwave_processing do
|
|
@photo.unprocessed_image.store! File.open(@fixture_name)
|
|
end
|
|
end
|
|
|
|
it 'should have text' do
|
|
@photo.text= "cool story, bro"
|
|
expect(@photo.save).to be true
|
|
end
|
|
|
|
it 'should remove its reference in user profile if it is referred' do
|
|
@photo.save
|
|
|
|
@user.profile.image_url = @photo.url(:thumb_large)
|
|
@user.person.save
|
|
@photo.destroy
|
|
expect(Person.find(@user.person.id).profile[:image_url]).to be_nil
|
|
end
|
|
|
|
it 'should not use the imported filename as the url' do
|
|
expect(@photo.url).not_to include @fixture_filename
|
|
expect(@photo.url(:thumb_medium)).not_to include ("/" + @fixture_filename)
|
|
end
|
|
|
|
it 'should save the image dimensions' do
|
|
expect(@photo.width).to eq(40)
|
|
expect(@photo.height).to eq(40)
|
|
end
|
|
end
|
|
|
|
context 'with a saved photo containing EXIF data' do
|
|
|
|
let(:base_path) { File.dirname(__FILE__) }
|
|
let(:public_path) { File.join(base_path, "../../public/") }
|
|
let(:photo_with_exif) { File.open(File.join(base_path, "..", "fixtures", "exif.jpg")) }
|
|
|
|
after do
|
|
FileUtils.rm_r Dir.glob(File.join(public_path, "uploads/images/*"))
|
|
end
|
|
|
|
it "should strip EXIF data" do
|
|
image = image_from a_photo_sent_by(bob)
|
|
|
|
expect(image.exif.length).to eq(0)
|
|
end
|
|
|
|
def a_photo_sent_by(user)
|
|
photo = user.build_post(:photo, user_file: photo_with_exif, to: @aspect.id)
|
|
|
|
with_carrierwave_processing do
|
|
photo.unprocessed_image.store! photo_with_exif
|
|
photo.save
|
|
end
|
|
|
|
photo
|
|
end
|
|
|
|
def image_from(photo)
|
|
photo_path = File.join(public_path, photo.unprocessed_image.store_dir, photo.unprocessed_image.filename)
|
|
MiniMagick::Image.new(photo_path)
|
|
end
|
|
end
|
|
|
|
describe 'non-image files' do
|
|
it 'should not store' do
|
|
file = File.open(@fail_fixture_name)
|
|
expect {
|
|
@photo.unprocessed_image.store! file
|
|
}.to raise_error CarrierWave::IntegrityError
|
|
end
|
|
end
|
|
|
|
describe "converting files" do
|
|
it "convert to webp" do
|
|
with_carrierwave_processing do
|
|
@photo.unprocessed_image.store! File.open(@fixture_name)
|
|
end
|
|
expect(@photo.remote_photo_name).to include(".webp")
|
|
end
|
|
end
|
|
|
|
describe "remote photos" do
|
|
it "should set the remote_photo on marshalling" do
|
|
url = @saved_photo.url
|
|
thumb_url = @saved_photo.url :thumb_medium
|
|
|
|
@saved_photo.height = 42
|
|
@saved_photo.width = 23
|
|
|
|
federation_photo = Diaspora::Federation::Entities.photo(@saved_photo)
|
|
|
|
@saved_photo.destroy
|
|
|
|
Diaspora::Federation::Receive.perform(federation_photo)
|
|
|
|
new_photo = Photo.find_by(guid: @saved_photo.guid)
|
|
expect(new_photo.url).to eq(url)
|
|
expect(new_photo.url(:thumb_medium)).to eq(thumb_url)
|
|
end
|
|
end
|
|
|
|
describe '#queue_processing_job' do
|
|
it 'should queue a job to process the images' do
|
|
expect(Workers::ProcessPhoto).to receive(:perform_async).with(@photo.id)
|
|
@photo.queue_processing_job
|
|
end
|
|
end
|
|
|
|
context "deletion" do
|
|
before do
|
|
@status_message = @user.build_post(:status_message, :text => "", :to => @aspect.id)
|
|
@status_message.photos << @photo2
|
|
@status_message.save
|
|
@status_message.reload
|
|
end
|
|
|
|
it 'is deleted with parent status message' do
|
|
expect {
|
|
@status_message.destroy
|
|
}.to change(Photo, :count).by(-1)
|
|
end
|
|
|
|
it 'will delete parent status message if message is otherwise empty' do
|
|
expect {
|
|
@photo2.destroy
|
|
}.to change(StatusMessage, :count).by(-1)
|
|
end
|
|
|
|
it 'will not delete parent status message if message had other content' do
|
|
@status_message.text = "Some text"
|
|
@status_message.save
|
|
@status_message.reload
|
|
|
|
expect {
|
|
@photo2.status_message.reload
|
|
@photo2.destroy
|
|
}.to_not change(StatusMessage, :count)
|
|
end
|
|
end
|
|
|
|
describe "#visible" do
|
|
context "with a current user" do
|
|
it "calls photos_from" do
|
|
expect(@user).to receive(:photos_from).with(@user.person, limit: :all, max_time: nil).and_call_original
|
|
Photo.visible(@user, @user.person)
|
|
end
|
|
|
|
it "does not contain pending photos" do
|
|
pending_photo = @user.post(:photo, pending: true, user_file: File.open(photo_fixture_name), to: @aspect)
|
|
expect(Photo.visible(@user, @user.person).ids).not_to include(pending_photo.id)
|
|
end
|
|
end
|
|
|
|
context "without a current user" do
|
|
it "returns all public photos" do
|
|
expect(Photo).to receive(:where).with(author_id: @user.person.id, public: true).and_call_original
|
|
Photo.visible(nil, @user.person)
|
|
end
|
|
end
|
|
end
|
|
end
|