diff options
Diffstat (limited to 'spec/models/user_detail_spec.rb')
-rw-r--r-- | spec/models/user_detail_spec.rb | 135 |
1 files changed, 135 insertions, 0 deletions
diff --git a/spec/models/user_detail_spec.rb b/spec/models/user_detail_spec.rb index 9189b9a1469..04964d36dcd 100644 --- a/spec/models/user_detail_spec.rb +++ b/spec/models/user_detail_spec.rb @@ -25,5 +25,140 @@ RSpec.describe UserDetail do describe '#bio' do it { is_expected.to validate_length_of(:bio).is_at_most(255) } end + + describe '#linkedin' do + it { is_expected.to validate_length_of(:linkedin).is_at_most(500) } + end + + describe '#twitter' do + it { is_expected.to validate_length_of(:twitter).is_at_most(500) } + end + + describe '#skype' do + it { is_expected.to validate_length_of(:skype).is_at_most(500) } + end + + describe '#location' do + it { is_expected.to validate_length_of(:location).is_at_most(500) } + end + + describe '#organization' do + it { is_expected.to validate_length_of(:organization).is_at_most(500) } + end + + describe '#website_url' do + it { is_expected.to validate_length_of(:website_url).is_at_most(500) } + end + end + + describe '.user_fields_changed?' do + let(:user) { create(:user) } + + context 'when user detail fields unchanged' do + it 'returns false' do + expect(described_class.user_fields_changed?(user)).to be false + end + + %i[linkedin location organization skype twitter website_url].each do |attr| + context "when #{attr} is changed" do + before do + user[attr] = 'new value' + end + + it 'returns true' do + expect(described_class.user_fields_changed?(user)).to be true + end + end + end + end + end + + describe '#sanitize_attrs' do + shared_examples 'sanitizes html' do |attr| + it 'sanitizes html tags' do + details = build_stubbed(:user_detail, attr => '<a href="//evil.com">https://example.com<a>') + expect { details.sanitize_attrs }.to change { details[attr] }.to('https://example.com') + end + + it 'sanitizes iframe scripts' do + details = build_stubbed(:user_detail, attr => '<iframe src=javascript:alert()><iframe>') + expect { details.sanitize_attrs }.to change { details[attr] }.to('') + end + + it 'sanitizes js scripts' do + details = build_stubbed(:user_detail, attr => '<script>alert("Test")</script>') + expect { details.sanitize_attrs }.to change { details[attr] }.to('') + end + end + + %i[linkedin skype twitter website_url].each do |attr| + it_behaves_like 'sanitizes html', attr + + it 'encodes HTML entities' do + details = build_stubbed(:user_detail, attr => 'test&attr') + expect { details.sanitize_attrs }.to change { details[attr] }.to('test&attr') + end + end + + %i[location organization].each do |attr| + it_behaves_like 'sanitizes html', attr + + it 'does not encode HTML entities' do + details = build_stubbed(:user_detail, attr => 'test&attr') + expect { details.sanitize_attrs }.not_to change { details[attr] } + end + end + + it 'sanitizes on validation' do + details = build(:user_detail) + + expect(details) + .to receive(:sanitize_attrs) + .at_least(:once) + .and_call_original + + details.save! + end + end + + describe '#assign_changed_fields_from_user' do + let(:user_detail) { build(:user_detail) } + + shared_examples 'syncs field with `user_details`' do |field| + it 'does not sync the field to `user_details` if unchanged' do + expect { user_detail.assign_changed_fields_from_user } + .to not_change { user_detail.public_send(field) } + end + + it 'syncs the field to `user_details` if changed' do + user_detail.user[field] = "new_value" + expect { user_detail.assign_changed_fields_from_user } + .to change { user_detail.public_send(field) } + .to("new_value") + end + + it 'truncates the field if too long' do + user_detail.user[field] = 'a' * (UserDetail::DEFAULT_FIELD_LENGTH + 1) + expect { user_detail.assign_changed_fields_from_user } + .to change { user_detail.public_send(field) } + .to('a' * UserDetail::DEFAULT_FIELD_LENGTH) + end + + it 'properly syncs nil field to `user_details' do + user_detail.user[field] = 'Test' + user_detail.user.save!(validate: false) + user_detail.user[field] = nil + expect { user_detail.assign_changed_fields_from_user } + .to change { user_detail.public_send(field) } + .to('') + end + end + + it_behaves_like 'syncs field with `user_details`', :linkedin + it_behaves_like 'syncs field with `user_details`', :location + it_behaves_like 'syncs field with `user_details`', :organization + it_behaves_like 'syncs field with `user_details`', :skype + it_behaves_like 'syncs field with `user_details`', :twitter + it_behaves_like 'syncs field with `user_details`', :website_url end end |