mirror of
https://github.com/discourse/discourse.git
synced 2024-11-25 19:53:37 +08:00
57ee779b1e
It seems that due to jobs being asynchronous and wrapping code in a DistributedMutex that by the time we run the `UserAvatar#update_gravatar!` job that the user/user email might be destroyed. This patch checks before a call to `user.email_hash` to make sure the user and primary email exist to prevent the exception. If not present, the job exits as there's nothing to do because we are probably running after the user was destroyed for some reason.
211 lines
5.8 KiB
Ruby
211 lines
5.8 KiB
Ruby
require 'rails_helper'
|
|
|
|
describe UserAvatar do
|
|
let(:user) { Fabricate(:user) }
|
|
let(:avatar) { user.create_user_avatar! }
|
|
|
|
describe '#update_gravatar!' do
|
|
let(:temp) { Tempfile.new('test') }
|
|
let(:upload) { Fabricate(:upload, user: user) }
|
|
|
|
describe "when working" do
|
|
|
|
before do
|
|
temp.binmode
|
|
# tiny valid png
|
|
temp.write(Base64.decode64("R0lGODlhAQABALMAAAAAAIAAAACAAICAAAAAgIAAgACAgMDAwICAgP8AAAD/AP//AAAA//8A/wD//wBiZCH5BAEAAA8ALAAAAAABAAEAAAQC8EUAOw=="))
|
|
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
|
|
|
|
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
|
|
|
|
freeze_time Time.now
|
|
|
|
stub_request(:get, "https://www.gravatar.com/avatar/#{avatar.user.email_hash}.png?d=404&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
|