Skip to content

Commit 5e4ea93

Browse files
authored
Merge pull request #2583 from mroderick/fix/gravatar-nil-email
fix(avatar): handle nil email with fallback to member-ID-based placeholder
2 parents 73b5fc1 + 8aba2ac commit 5e4ea93

5 files changed

Lines changed: 41 additions & 7 deletions

File tree

app/helpers/application_helper.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
module ApplicationHelper
2+
include DigestHelper
3+
24
def humanize_date(datetime, end_time = nil, with_time: false, with_year: false)
35
return I18n.l(datetime, format: :humanised_with_year) if with_year
46
return humanize_date_with_time(datetime, end_time) if with_time

app/helpers/digest_helper.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
module DigestHelper
2+
def md5_of(identifier)
3+
return '' if identifier.nil?
4+
5+
Digest::MD5.hexdigest(identifier.to_s.strip.downcase)
6+
end
7+
end

app/models/member.rb

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
class Member < ApplicationRecord
22
include Permissions
3+
include DigestHelper
34

45
enum :how_you_found_us, {
56
from_a_friend: 0,
@@ -99,7 +100,8 @@ def received_welcome_for?(subscription)
99100
end
100101

101102
def avatar(size = 100)
102-
"https://secure.gravatar.com/avatar/#{md5_email}?size=#{size}&default=identicon"
103+
identifier = email.presence || "member-#{id}@example.com"
104+
"https://secure.gravatar.com/avatar/#{md5_of(identifier)}?size=#{size}&default=identicon"
103105
end
104106

105107
def requires_additional_details?
@@ -172,10 +174,6 @@ def invitations_on(date)
172174
.where(attending: true)
173175
end
174176

175-
def md5_email
176-
Digest::MD5.hexdigest(email.strip.downcase)
177-
end
178-
179177
def rsvps(period:)
180178
time_period = "#{period}_rsvps"
181179

spec/helpers/application_helper_spec.rb

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,13 @@
1212

1313
describe '#number_to_currency' do
1414
it 'correctly formats a number to British pounds' do
15-
expect(helper.number_to_currency(20100)).to eq('£20,100')
15+
expect(helper.number_to_currency(20_100)).to eq('£20,100')
1616
end
1717
end
1818

1919
describe '#title and #get_title' do
2020
it 'sets page title with the given title name' do
21-
helper.title("Homapage")
21+
helper.title('Homapage')
2222

2323
expect(helper.retrieve_title).to eq('Homapage | codebar.io')
2424
end
@@ -60,4 +60,22 @@
6060
expect(title).to eq('Community partners')
6161
end
6262
end
63+
64+
describe '#md5_of' do
65+
it 'returns MD5 hash of lowercase string' do
66+
expect(helper.md5_of('Test@Example.COM')).to eq(Digest::MD5.hexdigest('test@example.com'))
67+
end
68+
69+
it 'handles nil gracefully' do
70+
expect(helper.md5_of(nil)).to eq('')
71+
end
72+
73+
it 'converts integer to string' do
74+
expect(helper.md5_of(123)).to eq(Digest::MD5.hexdigest('123'))
75+
end
76+
77+
it 'strips whitespace' do
78+
expect(helper.md5_of(' spaces@example.com ')).to eq(Digest::MD5.hexdigest('spaces@example.com'))
79+
end
80+
end
6381
end

spec/models/member_spec.rb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,15 @@
5858
expect(member.avatar).to eq("https://secure.gravatar.com/avatar/#{encrypted_email}?size=100&default=identicon")
5959
end
6060

61+
describe '#avatar' do
62+
let(:member) { Fabricate.build(:member, email: nil) }
63+
64+
it 'falls back to member ID based email' do
65+
encrypted_email = Digest::MD5.hexdigest("member-#{member.id}@example.com")
66+
expect(member.avatar).to eq("https://secure.gravatar.com/avatar/#{encrypted_email}?size=100&default=identicon")
67+
end
68+
end
69+
6170
describe '#recent_notes' do
6271
it 'returns no notes when member attented no workshops' do
6372
expect(member.workshop_invitations.attended.length).to eq(0)

0 commit comments

Comments
 (0)