# frozen_string_literal: true
require 'spec_helper'
RSpec.describe UserDetail do
it { is_expected.to belong_to(:user) }
it { is_expected.to define_enum_for(:registration_objective).with_values([:basics, :move_repository, :code_storage, :exploring, :ci, :other, :joining_team]).with_suffix }
describe 'validations' do
describe '#job_title' do
it { is_expected.not_to validate_presence_of(:job_title) }
it { is_expected.to validate_length_of(:job_title).is_at_most(200) }
end
describe '#pronouns' do
it { is_expected.not_to validate_presence_of(:pronouns) }
it { is_expected.to validate_length_of(:pronouns).is_at_most(50) }
end
describe '#pronunciation' do
it { is_expected.not_to validate_presence_of(:pronunciation) }
it { is_expected.to validate_length_of(:pronunciation).is_at_most(255) }
end
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 '#discord' do
it { is_expected.to validate_length_of(:discord).is_at_most(500) }
context 'when discord is set' do
let_it_be(:user_detail) { create(:user_detail) }
it 'accepts a valid discord user id' do
user_detail.discord = '1234567890123456789'
expect(user_detail).to be_valid
end
it 'throws an error when other url format is wrong' do
user_detail.discord = '123456789'
expect(user_detail).not_to be_valid
expect(user_detail.errors.full_messages).to match_array([_('Discord must contain only a discord user ID.')])
end
end
end
describe '#mastodon' do
it { is_expected.to validate_length_of(:mastodon).is_at_most(500) }
context 'when mastodon is set' do
let_it_be(:user_detail) { create(:user_detail) }
it 'accepts a valid mastodon username' do
user_detail.mastodon = '@robin@example.com'
expect(user_detail).to be_valid
end
it 'throws an error when mastodon username format is wrong' do
user_detail.mastodon = '@robin'
expect(user_detail).not_to be_valid
expect(user_detail.errors.full_messages).to match_array([_('Mastodon must contain only a mastodon username.')])
end
end
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) }
it 'only validates the website_url if it is changed' do
user_detail = create(:user_detail)
# `update_attribute` required to bypass current validations
# Validations on `User#website_url` were added after
# there was already data in the database and `UserDetail#website_url` is
# derived from `User#website_url` so this reproduces the state of some of
# our production data
user_detail.update_attribute(:website_url, 'NotAUrl')
expect(user_detail).to be_valid
user_detail.website_url = 'AlsoNotAUrl'
expect(user_detail).not_to be_valid
expect(user_detail.errors.full_messages).to match_array(["Website url is not a valid URL"])
end
end
end
describe '#save' do
let(:user_detail) do
create(
:user_detail,
bio: 'bio',
discord: '1234567890123456789',
linkedin: 'linkedin',
location: 'location',
mastodon: '@robin@example.com',
organization: 'organization',
skype: 'skype',
twitter: 'twitter',
website_url: 'https://example.com'
)
end
shared_examples 'prevents `nil` value' do |attr|
it 'converts `nil` to the empty string' do
user_detail[attr] = nil
expect { user_detail.save! }
.to change { user_detail[attr] }.to('')
.and not_change { user_detail.attributes.except(attr.to_s) }
end
end
it_behaves_like 'prevents `nil` value', :bio
it_behaves_like 'prevents `nil` value', :discord
it_behaves_like 'prevents `nil` value', :linkedin
it_behaves_like 'prevents `nil` value', :location
it_behaves_like 'prevents `nil` value', :mastodon
it_behaves_like 'prevents `nil` value', :organization
it_behaves_like 'prevents `nil` value', :skype
it_behaves_like 'prevents `nil` value', :twitter
it_behaves_like 'prevents `nil` value', :website_url
end
describe '#sanitize_attrs' do
shared_examples 'sanitizes html' do |attr|
it 'sanitizes html tags' do
details = build_stubbed(:user_detail, attr => 'https://example.com')
expect { details.sanitize_attrs }.to change { details[attr] }.to('https://example.com')
end
it 'sanitizes iframe scripts' do
details = build_stubbed(:user_detail, attr => '