discourse/spec/models/user_avatar_spec.rb

218 lines
6.1 KiB
Ruby

# frozen_string_literal: true
require 'rails_helper'
describe UserAvatar do
fab!(:user) { Fabricate(:user) }
let(:avatar) { user.create_user_avatar! }
describe '#update_gravatar!' do
let(:temp) { Tempfile.new('test') }
fab!(:upload) { Fabricate(:upload, user: user) }
describe "when working" do
before do
temp.binmode
# tiny valid png
temp.write(Base64.decode64("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAACklEQVR4nGMAAQAABQABDQottAAAAABJRU5ErkJggg=="))
temp.rewind
FileHelper.expects(:download).returns(temp)
end
after do
temp.unlink
end
it 'can update gravatars' do
freeze_time Time.now
expect { avatar.update_gravatar! }.to change { Upload.count }.by(1)
expect(avatar.gravatar_upload).to eq(Upload.last)
expect(avatar.last_gravatar_download_attempt).to eq(Time.now)
expect(user.reload.uploaded_avatar).to eq(nil)
expect do
avatar.destroy
end.to_not change { Upload.count }
end
it "updates gravatars even if uploads have been disabled" do
SiteSetting.authorized_extensions = ""
expect { avatar.update_gravatar! }.to change { Upload.count }.by(1)
expect(avatar.gravatar_upload).to eq(Upload.last)
end
describe 'when user has an existing custom upload' do
it "should not change the user's uploaded avatar" do
user.update!(uploaded_avatar: upload)
avatar.update!(
custom_upload: upload,
gravatar_upload: Fabricate(:upload, user: user)
)
avatar.update_gravatar!
expect(upload.reload).to eq(upload)
expect(user.reload.uploaded_avatar).to eq(upload)
expect(avatar.reload.custom_upload).to eq(upload)
expect(avatar.gravatar_upload).to eq(Upload.last)
end
end
describe 'when user has an existing gravatar' do
it "should update the user's uploaded avatar correctly" do
user.update!(uploaded_avatar: upload)
avatar.update!(gravatar_upload: upload)
avatar.update_gravatar!
# old upload to be cleaned up via clean_up_uploads
expect(Upload.find_by(id: upload.id)).not_to eq(nil)
new_upload = Upload.last
expect(user.reload.uploaded_avatar).to eq(new_upload)
expect(avatar.reload.gravatar_upload).to eq(new_upload)
end
end
end
describe "when failing" do
it "always update 'last_gravatar_download_attempt'" do
freeze_time Time.now
FileHelper.expects(:download).raises(SocketError)
expect do
expect { avatar.update_gravatar! }.to raise_error(SocketError)
end.to_not change { Upload.count }
expect(avatar.last_gravatar_download_attempt).to eq(Time.now)
end
end
describe "404 should be silent, nothing to do really" do
it "does nothing when avatar is 404" do
SecureRandom.stubs(:urlsafe_base64).returns("5555")
freeze_time Time.now
stub_request(:get, "https://www.gravatar.com/avatar/#{avatar.user.email_hash}.png?d=404&reset_cache=5555&s=360").
to_return(status: 404, body: "", headers: {})
expect do
avatar.update_gravatar!
end.to_not change { Upload.count }
expect(avatar.last_gravatar_download_attempt).to eq(Time.now)
end
end
it "should not raise an error when there's no primary_email" do
avatar.user.primary_email.destroy
avatar.user.reload
# If raises an error, test fails
avatar.update_gravatar!
end
end
context '.import_url_for_user' do
it 'creates user_avatar record if missing' do
user = Fabricate(:user)
user.user_avatar.destroy
user.reload
FileHelper.stubs(:download).returns(file_from_fixtures("logo.png"))
UserAvatar.import_url_for_user("logo.png", user)
user.reload
expect(user.uploaded_avatar_id).not_to eq(nil)
expect(user.user_avatar.custom_upload_id).to eq(user.uploaded_avatar_id)
end
it 'can leave gravatar alone' do
upload = Fabricate(:upload)
user = Fabricate(:user, uploaded_avatar_id: upload.id)
user.user_avatar.update_columns(gravatar_upload_id: upload.id)
stub_request(:get, "http://thisfakesomething.something.com/")
.to_return(status: 200, body: file_from_fixtures("logo.png"), headers: {})
url = "http://thisfakesomething.something.com/"
expect do
UserAvatar.import_url_for_user(url, user, override_gravatar: false)
end.to change { Upload.count }.by(1)
user.reload
expect(user.uploaded_avatar_id).to eq(upload.id)
last_id = Upload.last.id
expect(last_id).not_to eq(upload.id)
expect(user.user_avatar.custom_upload_id).to eq(last_id)
end
describe 'when avatar url returns an invalid status code' do
it 'should not do anything' do
stub_request(:get, "http://thisfakesomething.something.com/")
.to_return(status: 500, body: "", headers: {})
url = "http://thisfakesomething.something.com/"
expect do
UserAvatar.import_url_for_user(url, user)
end.to_not change { Upload.count }
user.reload
expect(user.uploaded_avatar_id).to eq(nil)
expect(user.user_avatar.custom_upload_id).to eq(nil)
end
end
end
describe "ensure_consistency!" do
it "will clean up dangling avatars" do
upload1 = Fabricate(:upload)
upload2 = Fabricate(:upload)
user_avatar = Fabricate(:user).user_avatar
user_avatar.update_columns(
gravatar_upload_id: upload1.id,
custom_upload_id: upload2.id
)
upload1.destroy!
upload2.destroy!
user_avatar.reload
expect(user_avatar.gravatar_upload_id).to eq(nil)
expect(user_avatar.custom_upload_id).to eq(nil)
user_avatar.update_columns(
gravatar_upload_id: upload1.id,
custom_upload_id: upload2.id
)
UserAvatar.ensure_consistency!
user_avatar.reload
expect(user_avatar.gravatar_upload_id).to eq(nil)
expect(user_avatar.custom_upload_id).to eq(nil)
end
end
end