# frozen_string_literal: true require 'spec_helper' describe User do let(:user_admin) { create(:admin) } let(:conference) { create(:conference, short_title: 'oSC16', title: 'openSUSE Conference 2016') } let(:conference2) { create(:conference, short_title: 'oSC15', title: 'openSUSE Conference 2015') } let(:organizer_role) { Role.find_by(name: 'organizer', resource: conference) } let(:cfp_role) { Role.find_by(name: 'cfp', resource: conference) } let(:volunteers_coordinator_role) { Role.find_by(name: 'volunteers_coordinator', resource: conference) } let(:organizer) { create(:organizer, resource: conference) } let(:user) { create(:user) } let(:user_disabled) { create(:user, :disabled) } let(:event1) { create(:event, program: conference.program) } let(:another_conference) { create(:conference) } let(:event2) { create(:event, program: another_conference.program) } let(:registration) { create(:registration, user: user, conference: conference) } let(:events_registration) { create(:events_registration, event: event1, registration: registration) } describe 'validation' do it { is_expected.to validate_presence_of(:email) } it { is_expected.to validate_presence_of(:username) } it { is_expected.to validate_uniqueness_of(:username).ignoring_case_sensitivity } it 'biography can not have more than 150 words' do # Text with 151 words long_text = <<-EOS Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean vestibulum, augue ut accumsan feugiat, mauris eros accumsan nunc, volutpat vulputate eros orci quis nulla. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed varius orci ut lectus convallis, et ultrices ex finibus. Praesent orci augue, aliquet at cursus at, placerat id ligula. Vestibulum a mauris non felis pretium laoreet. Cras vel nisl convallis, pharetra ipsum at, mattis erat. Praesent in lectus felis. Fusce eros mauris, euismod lobortis metus id, tristique scelerisque nisl. Suspendisse potenti. Suspendisse ac metus magna. Integer lobortis pharetra eros euismod fringilla. Phasellus vitae orci vel magna laoreet mattis non eu neque. Mauris ac dictum leo. Nullam dapibus convallis molestie. Integer dignissim massa at odio feugiat tempus. Pellentesque ultrices rutrum eros, a pellentesque lorem auctor in. Suspendisse sollicitudin dolor vitae justo dignissim, a condimentum turpis molestie. Aenean scelerisque, arcu eu congue mollis, nibh nulla finibus. EOS expect(build(:user, biography: long_text)).to_not be_valid end end describe 'association' do it { is_expected.to have_many(:openids) } it { is_expected.to have_many(:event_users).dependent(:destroy) } it { is_expected.to have_many(:events).through(:event_users) } it { is_expected.to have_many(:registrations).dependent(:destroy) } it { is_expected.to have_many(:events_registrations).through(:registrations) } it { is_expected.to have_many(:ticket_purchases).dependent(:destroy) } it { is_expected.to have_many(:tickets).through(:ticket_purchases) } it { is_expected.to have_many(:votes).dependent(:destroy) } it { is_expected.to have_many(:subscriptions).dependent(:destroy) } end describe 'scope and nested attribute' do it { should accept_nested_attributes_for :roles } describe '.admin' do it 'includes users with admin flag' do expect(User.admin).to include(user_admin) end it 'excludes users without admin flag' do expect(User.admin).not_to include(user) end end describe '.active' do it 'includes users without is_disabled flag' do expect(User.active).to include(user) end it 'excludes users with is_disabled flag' do expect(User.active).not_to include(user_disabled) end end describe '.comment_notifiable' do let(:cfp_user) { create(:user, role_ids: [cfp_role.id]) } it 'includes organizer and cfp user' do expect(User.comment_notifiable(conference)).to include(organizer, cfp_user) end it 'excludes ordinary user' do expect(User.comment_notifiable(conference)).not_to include(user) end end describe 'user distribution scopes' do it 'scopes recent users' do create(:user, last_sign_in_at: Date.today - 3.months + 1.day) # active expect(User.recent.count).to eq(1) end it 'scopes unconfirmed users' do create(:user, confirmed_at: nil) # unconfirmed expect(User.unconfirmed.count).to eq(1) end it 'scopes dead users' do create(:user, last_sign_in_at: Time.zone.now - 1.year - 1.day) # dead expect(User.dead.count).to eq(1) end end end describe 'methods' do describe '#attended_event?' do context 'user has attended to the event' do before do events_registration.update_attribute(:attended, true) end it 'returns true' do expect(user.attended_event?(event1)).to be true end end context 'user did not register for the event' do it 'returns false' do expect(user.attended_event?(event1)).to be false end end context 'user registered for the event, but did not attend' do before do events_registration end it 'returns false' do expect(user.attended_event?(event1)).to be false end end end describe '#name' do it 'returns the username as name if there is not name' do user = create(:user, name: nil) expect(user.name).to eq(user.username) end end describe '#registered_to_event?' do context 'user has registered to event' do before do events_registration end it 'returns true' do expect(user.registered_to_event?(event1)).to be true end end context 'user has not registered to event' do it 'returns false' do expect(user.registered_to_event?(event1)).to be false end end end describe '#subscribed?' do context 'user has subscribed to conference' do before { create(:subscription, user: user, conference: conference) } it 'returns true' do expect(user.subscribed?(conference)).to be true end end context 'user has not subscribed to conference' do it 'return false' do expect(user.subscribed?(conference)).to be false end end end describe '.supports?' do context 'user has bought tickets' do before { create(:ticket_purchase, user: user, conference: conference) } it 'returns true' do expect(user.supports?(conference)).to be true end end context 'user has not bought any ticket' do it 'return false' do expect(user.supports?(conference)).to be false end end end describe '.for_ichain_username' do before { user.update_attribute(:current_sign_in_at, Date.new(2014, 12, 12)) } context 'user exists' do it 'updates last_sign_in_at of user' do expect do User.for_ichain_username(user.username, email: user.email) user.reload end.to change { user.last_sign_in_at } end it 'updates current_sign_in_at of user' do expect do User.for_ichain_username(user.username, email: user.email) user.reload end.to change { user.current_sign_in_at } end end context 'user is disabled' do before { user.update_attribute(:is_disabled, true) } it 'User.for_ichain_username raises exception if user is disabled' do expect{ User.for_ichain_username(user.username, email: user.email) } .to raise_error(UserDisabled) end end end describe '.find_for_database_authentication' do context 'login with username' do it 'can find user by jumbled username' do scrambled_username = user.username.chars.map{|c| rand > 0.5 ? c.capitalize : c}.join expect(User.find_for_database_authentication(login: scrambled_username)).to eq(user) end end context 'login with email' do it 'can find user by jumbled email' do scrambled_email = user.email.chars.map{|c| rand > 0.5 ? c.capitalize : c}.join expect(User.find_for_database_authentication(login: scrambled_email)).to eq(user) end end end describe '.find_for_auth' do let(:auth) do OmniAuth::AuthHash.new(provider: 'google', uid: 'google-test-uid-1', info: { name: 'new user name', email: 'test-1@gmail.com', username: 'newuser' }, credentials: { token: 'mock_token', secret: 'mock_secret' } ) end context 'user is not signed in' do context 'first visit to website' do before { @auth_user = User.find_for_auth(auth, nil) } it 'initializes new user' do expect(@auth_user.new_record?).to be true end it 'sets name, email, username and password' do regex_base64 = %r{^(?:[A-Za-z_\-0-9+\/]{4}\n?)*(?:[A-Za-z_\-0-9+\/]{2}|[A-Za-z_\-0-9+\/]{3}=)?$} expect(@auth_user.name).to eq 'new user name' expect(@auth_user.email).to eq 'test-1@gmail.com' expect(@auth_user.username).to eq 'newuser' expect(@auth_user.password).to match regex_base64 end end context 'user returns to website' do let!(:auth_user) { create(:user, email: 'test-1@gmail.com') } it 'finds corresponding user' do expect(User.find_for_auth(auth, nil)).to eq auth_user end end end end describe '#get_roles' do let(:conf2_organizer_role) { Role.find_by(name: 'organizer', resource: conference2) } before do user.update_attribute(:role_ids, [organizer_role.id, cfp_role.id, conf2_organizer_role.id]) end it 'returns hash of role and conference' do expected_hash = { 'organizer' => %w[oSC16 oSC15], 'cfp' => ['oSC16'] } expect(user.get_roles).to eq expected_hash end end describe '#confirmed?' do context 'confirmed user' do it 'returns true' do expect(user.confirmed?).to be true end end context 'unconfirmed user' do before { user.update_attribute(:confirmed_at, nil) } it 'returns false' do expect(user.confirmed?).to be false end end end describe 'proposals methods' do let(:submitter) { create(:user) } let(:speaker) { create(:user) } let(:event1) { create(:event, program: conference.program) } let(:event2) { create(:event, program: conference.program) } before do event1.event_users << create(:event_user, user: submitter, event_role: 'submitter') event2.event_users << create(:event_user, user: submitter, event_role: 'submitter') event1.event_users << create(:event_user, user: speaker, event_role: 'speaker') end describe '#proposals' do it 'returns events submitted by user' do expect(submitter.proposals(conference)).to match [event1, event2] end it 'returns events in which user is a speaker' do expect(speaker.proposals(conference)).to match [event1] end end describe '#proposal_count' do it 'returns number of events submitted by user' do expect(submitter.proposal_count(conference)).to eq 2 end it 'returns number of events in which the user is a speaker' do expect(speaker.proposal_count(conference)).to eq 1 end end end end describe 'rolify' do it 'returns the correct role' do expect(user_admin.is_admin).to be(true) expect(organizer.roles.first).to eq(organizer_role) end it 'returns the correct roles' do roles = [organizer_role.id, cfp_role.id] another_user = create(:user, email: 'participant@example.de') another_user.role_ids = roles another_user.save expect(another_user.roles.length).to eq(2) expect(another_user.roles[0]).to eq(organizer_role) expect(another_user.roles[1]).to eq(cfp_role) end describe '#has_cached_role?' do describe 'when user has a role' do it 'returns true when the user has the role' do expect(organizer.has_cached_role?('organizer', conference)).to be true end it 'returns false when the user does not have the role' do user = create(:user, role_ids: cfp_role.id) expect(user.has_cached_role?('organizer', conference)).to be false end end it 'returns false when the user does not have a role' do user = create(:user, role_ids: []) expect(user.has_cached_role?('organizer', conference)).to be false end end end describe 'assigns admin attribute' do it 'to second user when first user is deleted_user' do deleted_user = User.find_by(email: 'deleted@localhost.osem') expect(deleted_user.is_admin).to be false user_after_deleted = create(:admin) expect(user_after_deleted.is_admin).to be true end end describe 'does not assign admin attribute' do it 'when first user is not deleted_user' do first_user = create(:user) expect(first_user.is_admin).to be false second_user = create(:user) expect(second_user.is_admin).to be false end end describe 'has_many events_registrations' do before :each do registration1 = create(:registration, user: user, conference: conference) registration2 = create(:registration, user: user, conference: another_conference) @events_registration1 = create(:events_registration, registration: registration1, event: event1) @events_registration2 = create(:events_registration, registration: registration2, event: event2) end it 'returns all the events the user registered to' do expect(user.events_registrations).to eq [@events_registration1, @events_registration2] end end describe '.omniauth_providers' do it 'contains providers' do expect(User.omniauth_providers).to eq [:suse, :google, :facebook, :github] end end end