2019-04-29 20:27:42 -04:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2022-07-27 22:27:38 -04:00
|
|
|
RSpec.describe Invite do
|
2021-03-25 12:26:22 -04:00
|
|
|
fab!(:user) { Fabricate(:user) }
|
2022-01-18 07:38:31 -05:00
|
|
|
let(:xss_email) { "<b onmouseover=alert('wufff!')>email</b><script>alert('test');</script>@test.com" }
|
|
|
|
let(:escaped_email) { "<b onmouseover=alert('wufff!')>email</b><script>alert('test');</script>@test.com" }
|
2013-02-05 14:16:51 -05:00
|
|
|
|
2022-07-27 12:14:14 -04:00
|
|
|
describe 'Validators' do
|
2021-03-25 12:26:22 -04:00
|
|
|
it { is_expected.to validate_presence_of :invited_by_id }
|
|
|
|
it { is_expected.to rate_limit }
|
2013-02-05 14:16:51 -05:00
|
|
|
|
2021-03-25 12:26:22 -04:00
|
|
|
it 'allows invites with valid emails' do
|
|
|
|
invite = Fabricate.build(:invite, email: 'test@example.com', invited_by: user)
|
|
|
|
expect(invite).to be_valid
|
2013-02-05 14:16:51 -05:00
|
|
|
end
|
2019-02-06 12:08:06 -05:00
|
|
|
|
2022-01-18 07:38:31 -05:00
|
|
|
it 'escapes the invalid email before attaching the error message' do
|
|
|
|
invite = Fabricate.build(:invite, email: xss_email)
|
|
|
|
|
2020-06-02 22:13:25 -04:00
|
|
|
expect(invite.valid?).to eq(false)
|
2022-01-18 07:38:31 -05:00
|
|
|
expect(invite.errors.full_messages).to include(I18n.t('invite.invalid_email', email: escaped_email))
|
2019-02-06 12:08:06 -05:00
|
|
|
end
|
2014-10-09 10:44:15 -04:00
|
|
|
|
2021-03-25 12:26:22 -04:00
|
|
|
it 'does not allow an invite with the same email as an existing user' do
|
|
|
|
invite = Fabricate.build(:invite, email: Fabricate(:user).email, invited_by: user)
|
|
|
|
expect(invite).not_to be_valid
|
|
|
|
|
|
|
|
invite = Fabricate.build(:invite, email: user.email, invited_by: user)
|
2014-12-31 09:55:03 -05:00
|
|
|
expect(invite).not_to be_valid
|
2014-10-09 10:44:15 -04:00
|
|
|
end
|
|
|
|
|
2021-03-25 12:26:22 -04:00
|
|
|
it 'does not allow an invite with blocked email' do
|
|
|
|
invite = Invite.create(email: 'test@mailinator.com', invited_by: user)
|
|
|
|
expect(invite).not_to be_valid
|
2014-10-09 10:44:15 -04:00
|
|
|
end
|
|
|
|
|
2021-03-25 12:26:22 -04:00
|
|
|
it 'does not allow an invalid email address' do
|
2020-06-02 22:13:25 -04:00
|
|
|
invite = Fabricate.build(:invite, email: 'asjdso')
|
|
|
|
expect(invite.valid?).to eq(false)
|
2021-04-15 07:46:32 -04:00
|
|
|
expect(invite.errors.full_messages).to include(I18n.t('invite.invalid_email', email: invite.email))
|
2020-06-02 22:13:25 -04:00
|
|
|
end
|
2021-12-13 00:39:14 -05:00
|
|
|
|
|
|
|
it 'allows only valid domains' do
|
2022-09-30 06:35:00 -04:00
|
|
|
invite = Fabricate.build(:invite, email: nil, domain: 'example', invited_by: user)
|
2021-12-13 00:39:14 -05:00
|
|
|
expect(invite).not_to be_valid
|
|
|
|
|
2022-09-30 06:35:00 -04:00
|
|
|
invite = Fabricate.build(:invite, email: nil, domain: 'example.com', invited_by: user)
|
2021-12-13 00:39:14 -05:00
|
|
|
expect(invite).to be_valid
|
|
|
|
end
|
2022-09-30 06:35:00 -04:00
|
|
|
|
|
|
|
it 'allows only email or only domain to be present' do
|
|
|
|
invite = Fabricate.build(:invite, email: nil, invited_by: user)
|
|
|
|
expect(invite).to be_valid
|
|
|
|
|
|
|
|
invite = Fabricate.build(:invite, email: nil, domain: 'example.com', invited_by: user)
|
|
|
|
expect(invite).to be_valid
|
|
|
|
|
|
|
|
invite = Fabricate.build(:invite, email: 'test@example.com', invited_by: user)
|
|
|
|
expect(invite).to be_valid
|
|
|
|
|
|
|
|
invite = Fabricate.build(:invite, email: 'test@example.com', domain: 'example.com', invited_by: user)
|
|
|
|
expect(invite).not_to be_valid
|
|
|
|
expect(invite.errors.full_messages).to include(I18n.t('invite.email_xor_domain'))
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'checks if redemption_count is less or equal than max_redemptions_allowed' do
|
|
|
|
invite = Fabricate.build(:invite, redemption_count: 2, max_redemptions_allowed: 1, invited_by: user)
|
|
|
|
expect(invite).not_to be_valid
|
|
|
|
expect(invite.errors.full_messages.first).to include(I18n.t('invite.redemption_count_less_than_max', max_redemptions_allowed: 1))
|
|
|
|
end
|
2014-10-09 10:44:15 -04:00
|
|
|
end
|
|
|
|
|
2022-07-27 12:14:14 -04:00
|
|
|
describe 'before_save' do
|
2021-04-14 05:15:56 -04:00
|
|
|
it 'regenerates the email token when email is changed' do
|
|
|
|
invite = Fabricate(:invite, email: 'test@example.com')
|
|
|
|
token = invite.email_token
|
|
|
|
|
|
|
|
invite.update!(email: 'test@example.com')
|
|
|
|
expect(invite.email_token).to eq(token)
|
|
|
|
|
|
|
|
invite.update!(email: 'test2@example.com')
|
|
|
|
expect(invite.email_token).not_to eq(token)
|
|
|
|
|
|
|
|
invite.update!(email: nil)
|
|
|
|
expect(invite.email_token).to eq(nil)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2022-07-27 06:21:10 -04:00
|
|
|
describe '.generate' do
|
2021-03-25 12:26:22 -04:00
|
|
|
it 'saves an invites' do
|
|
|
|
invite = Invite.generate(user, email: 'TEST@EXAMPLE.COM')
|
|
|
|
expect(invite.invite_key).to be_present
|
|
|
|
expect(invite.email).to eq('test@example.com')
|
|
|
|
end
|
2013-02-05 14:16:51 -05:00
|
|
|
|
2021-03-25 12:26:22 -04:00
|
|
|
it 'can succeed for staged users emails' do
|
|
|
|
Fabricate(:staged, email: 'test@example.com')
|
|
|
|
invite = Invite.generate(user, email: 'test@example.com')
|
|
|
|
expect(invite.email).to eq('test@example.com')
|
2013-02-05 14:16:51 -05:00
|
|
|
end
|
|
|
|
|
2021-03-25 12:26:22 -04:00
|
|
|
it 'raises an error when inviting an existing user' do
|
|
|
|
expect { Invite.generate(user, email: user.email) }
|
|
|
|
.to raise_error(Invite::UserExists)
|
|
|
|
end
|
2013-02-25 11:42:20 -05:00
|
|
|
|
2022-01-18 07:38:31 -05:00
|
|
|
it 'escapes the email_address when raising an existing user error' do
|
|
|
|
user.email = xss_email
|
|
|
|
user.save(validate: false)
|
|
|
|
|
|
|
|
expect { Invite.generate(user, email: user.email) }
|
|
|
|
.to raise_error(
|
|
|
|
Invite::UserExists,
|
2022-05-10 11:45:43 -04:00
|
|
|
I18n.t('invite.user_exists', email: escaped_email)
|
2022-01-18 07:38:31 -05:00
|
|
|
)
|
|
|
|
end
|
|
|
|
|
2022-07-27 12:14:14 -04:00
|
|
|
context 'with email' do
|
2021-04-14 05:15:56 -04:00
|
|
|
it 'can be created and a job is enqueued to email the invite' do
|
2021-03-25 12:26:22 -04:00
|
|
|
invite = Invite.generate(user, email: 'test@example.com')
|
2021-04-14 05:15:56 -04:00
|
|
|
expect(invite.email).to eq('test@example.com')
|
2021-03-25 12:26:22 -04:00
|
|
|
expect(invite.emailed_status).to eq(Invite.emailed_status_types[:sending])
|
2021-04-14 05:15:56 -04:00
|
|
|
expect(invite.email_token).not_to eq(nil)
|
2021-03-25 12:26:22 -04:00
|
|
|
expect(Jobs::InviteEmail.jobs.size).to eq(1)
|
2013-02-05 14:16:51 -05:00
|
|
|
end
|
|
|
|
|
2021-03-25 12:26:22 -04:00
|
|
|
it 'can skip the job to email the invite' do
|
|
|
|
invite = Invite.generate(user, email: 'test@example.com', skip_email: true)
|
|
|
|
expect(invite.emailed_status).to eq(Invite.emailed_status_types[:not_required])
|
|
|
|
expect(Jobs::InviteEmail.jobs.size).to eq(0)
|
2019-07-19 01:59:12 -04:00
|
|
|
end
|
|
|
|
|
2021-03-25 12:26:22 -04:00
|
|
|
it 'can invite the same user after their invite was destroyed' do
|
|
|
|
Invite.generate(user, email: 'test@example.com').destroy!
|
|
|
|
invite = Invite.generate(user, email: 'test@example.com')
|
|
|
|
expect(invite).to be_present
|
2013-02-05 14:16:51 -05:00
|
|
|
end
|
2021-03-25 12:26:22 -04:00
|
|
|
end
|
2013-02-05 14:16:51 -05:00
|
|
|
|
2022-07-27 12:14:14 -04:00
|
|
|
context 'with link' do
|
2021-03-25 12:26:22 -04:00
|
|
|
it 'does not enqueue a job to email the invite' do
|
|
|
|
invite = Invite.generate(user, skip_email: true)
|
|
|
|
expect(invite.emailed_status).to eq(Invite.emailed_status_types[:not_required])
|
|
|
|
expect(Jobs::InviteEmail.jobs.size).to eq(0)
|
|
|
|
end
|
2013-02-05 14:16:51 -05:00
|
|
|
|
2021-03-25 12:26:22 -04:00
|
|
|
it 'can be created' do
|
|
|
|
invite = Invite.generate(user, max_redemptions_allowed: 5)
|
|
|
|
expect(invite.max_redemptions_allowed).to eq(5)
|
|
|
|
expect(invite.expires_at.to_date).to eq(SiteSetting.invite_expiry_days.days.from_now.to_date)
|
|
|
|
expect(invite.emailed_status).to eq(Invite.emailed_status_types[:not_required])
|
|
|
|
expect(invite.is_invite_link?).to eq(true)
|
2021-04-14 05:15:56 -04:00
|
|
|
expect(invite.email_token).to eq(nil)
|
2021-03-25 12:26:22 -04:00
|
|
|
end
|
2013-02-05 14:16:51 -05:00
|
|
|
|
2021-03-25 12:26:22 -04:00
|
|
|
it 'checks for max_redemptions_allowed range' do
|
|
|
|
SiteSetting.invite_link_max_redemptions_limit_users = 3
|
|
|
|
expect { Invite.generate(user, max_redemptions_allowed: 4) }.to raise_error(ActiveRecord::RecordInvalid)
|
2013-02-05 14:16:51 -05:00
|
|
|
|
2021-03-25 12:26:22 -04:00
|
|
|
SiteSetting.invite_link_max_redemptions_limit = 3
|
|
|
|
expect { Invite.generate(Fabricate(:admin), max_redemptions_allowed: 4) }.to raise_error(ActiveRecord::RecordInvalid)
|
|
|
|
end
|
|
|
|
end
|
2018-12-10 17:24:02 -05:00
|
|
|
|
2021-03-25 12:26:22 -04:00
|
|
|
context 'when sending an invite to the same user' do
|
|
|
|
fab!(:invite) { Invite.generate(user, email: 'test@example.com') }
|
2019-12-17 10:13:49 -05:00
|
|
|
|
2021-03-25 12:26:22 -04:00
|
|
|
it 'returns the original invite' do
|
|
|
|
%w{test@EXAMPLE.com TEST@example.com}.each do |email|
|
|
|
|
expect(Invite.generate(user, email: email)).to eq(invite)
|
2019-12-17 10:13:49 -05:00
|
|
|
end
|
2021-03-25 12:26:22 -04:00
|
|
|
end
|
2019-12-17 10:13:49 -05:00
|
|
|
|
2021-03-25 12:26:22 -04:00
|
|
|
it 'updates timestamp of existing invite' do
|
|
|
|
freeze_time
|
|
|
|
invite.update!(created_at: 10.days.ago)
|
|
|
|
resend_invite = Invite.generate(user, email: 'test@example.com')
|
|
|
|
expect(resend_invite).to eq(invite)
|
|
|
|
expect(resend_invite.created_at).to eq_time(Time.zone.now)
|
|
|
|
end
|
2018-12-10 17:24:02 -05:00
|
|
|
|
2021-03-25 12:26:22 -04:00
|
|
|
it 'returns a new invite if the other has expired' do
|
|
|
|
SiteSetting.invite_expiry_days = 1
|
|
|
|
invite.update!(expires_at: 2.days.ago)
|
2018-12-10 17:24:02 -05:00
|
|
|
|
2021-03-25 12:26:22 -04:00
|
|
|
new_invite = Invite.generate(user, email: 'test@example.com')
|
|
|
|
expect(new_invite).not_to eq(invite)
|
|
|
|
expect(new_invite).not_to be_expired
|
|
|
|
end
|
2018-12-10 17:24:02 -05:00
|
|
|
|
2021-03-25 12:26:22 -04:00
|
|
|
it 'returns a new invite when invited by a different user' do
|
|
|
|
invite = Invite.generate(user, email: 'test@example.com')
|
|
|
|
expect(invite.email).to eq('test@example.com')
|
2018-12-10 17:24:02 -05:00
|
|
|
|
2021-03-25 12:26:22 -04:00
|
|
|
another_invite = Invite.generate(Fabricate(:user), email: 'test@example.com')
|
|
|
|
expect(another_invite.email).to eq('test@example.com')
|
2018-12-10 17:24:02 -05:00
|
|
|
|
2021-03-25 12:26:22 -04:00
|
|
|
expect(invite.invite_key).not_to eq(another_invite.invite_key)
|
2013-02-05 14:16:51 -05:00
|
|
|
end
|
2022-08-10 01:39:26 -04:00
|
|
|
|
|
|
|
context "when email is already invited 3 times" do
|
|
|
|
before do
|
|
|
|
RateLimiter.enable
|
|
|
|
3.times do
|
|
|
|
Invite.generate(user, email: "test@example.com")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
after do
|
|
|
|
RateLimiter.clear_all!
|
|
|
|
end
|
|
|
|
|
|
|
|
it "raises an error" do
|
|
|
|
expect { Invite.generate(user, email: "test@example.com") }
|
|
|
|
.to raise_error(RateLimiter::LimitExceeded)
|
|
|
|
end
|
|
|
|
end
|
2013-02-05 14:16:51 -05:00
|
|
|
end
|
2020-06-09 11:19:32 -04:00
|
|
|
|
2022-07-27 12:14:14 -04:00
|
|
|
context 'when inviting to a topic' do
|
2021-03-25 12:26:22 -04:00
|
|
|
fab!(:topic) { Fabricate(:topic) }
|
|
|
|
let(:invite) { Invite.generate(topic.user, email: 'test@example.com', topic: topic) }
|
2020-06-09 11:19:32 -04:00
|
|
|
|
2021-03-25 12:26:22 -04:00
|
|
|
it 'belongs to the topic' do
|
|
|
|
expect(topic.invites).to contain_exactly(invite)
|
|
|
|
expect(invite.topics).to contain_exactly(topic)
|
2020-06-09 11:19:32 -04:00
|
|
|
end
|
|
|
|
|
2021-03-25 12:26:22 -04:00
|
|
|
context 'when adding to another topic' do
|
|
|
|
fab!(:another_topic) { Fabricate(:topic, user: topic.user) }
|
2020-06-09 11:19:32 -04:00
|
|
|
|
2021-03-25 12:26:22 -04:00
|
|
|
it 'should be the same invite' do
|
|
|
|
new_invite = Invite.generate(topic.user, email: 'test@example.com', topic: another_topic)
|
|
|
|
expect(invite).to eq(new_invite)
|
|
|
|
expect(invite.topics).to contain_exactly(topic, another_topic)
|
|
|
|
expect(topic.invites).to contain_exactly(invite)
|
|
|
|
expect(another_topic.invites).to contain_exactly(invite)
|
|
|
|
end
|
2020-06-09 11:19:32 -04:00
|
|
|
end
|
|
|
|
end
|
2013-02-05 14:16:51 -05:00
|
|
|
end
|
|
|
|
|
2022-07-27 06:21:10 -04:00
|
|
|
describe '#redeem' do
|
2021-03-25 12:26:22 -04:00
|
|
|
fab!(:invite) { Fabricate(:invite) }
|
2013-02-05 14:16:51 -05:00
|
|
|
|
2021-03-25 12:26:22 -04:00
|
|
|
it 'works' do
|
|
|
|
user = invite.redeem
|
|
|
|
expect(invite.invited_users.map(&:user)).to contain_exactly(user)
|
|
|
|
expect(user.is_a?(User)).to eq(true)
|
|
|
|
expect(user.trust_level).to eq(SiteSetting.default_invitee_trust_level)
|
|
|
|
expect(user.send_welcome_message).to eq(true)
|
2018-01-19 09:29:15 -05:00
|
|
|
|
2021-03-25 12:26:22 -04:00
|
|
|
expect(invite.reload.redemption_count).to eq(1)
|
|
|
|
expect(invite.redeem).to be_blank
|
2018-01-19 09:29:15 -05:00
|
|
|
end
|
2013-02-05 14:16:51 -05:00
|
|
|
|
2021-03-29 07:03:19 -04:00
|
|
|
it 'keeps custom fields' do
|
|
|
|
user_field = Fabricate(:user_field)
|
|
|
|
staged_user = Fabricate(:user, staged: true, email: invite.email)
|
|
|
|
staged_user.set_user_field(user_field.id, 'some value')
|
|
|
|
staged_user.save_custom_fields
|
|
|
|
|
|
|
|
expect(invite.redeem).to eq(staged_user)
|
|
|
|
expect(staged_user.reload.user_fields[user_field.id.to_s]).to eq('some value')
|
|
|
|
end
|
|
|
|
|
2013-02-05 14:16:51 -05:00
|
|
|
it 'creates a notification for the invitee' do
|
2021-03-25 12:26:22 -04:00
|
|
|
expect { invite.redeem }.to change { Notification.count }
|
2013-02-05 14:16:51 -05:00
|
|
|
end
|
|
|
|
|
2021-03-25 12:26:22 -04:00
|
|
|
it 'does not work with expired invites' do
|
|
|
|
invite.update!(expires_at: 1.day.ago)
|
2014-12-31 09:55:03 -05:00
|
|
|
expect(invite.redeem).to be_blank
|
2013-02-05 14:16:51 -05:00
|
|
|
end
|
|
|
|
|
2021-03-25 12:26:22 -04:00
|
|
|
it 'does not work with deleted invites' do
|
|
|
|
invite.trash!
|
2014-12-31 09:55:03 -05:00
|
|
|
expect(invite.redeem).to be_blank
|
2013-02-05 14:16:51 -05:00
|
|
|
end
|
|
|
|
|
2021-03-25 12:26:22 -04:00
|
|
|
it 'does not work with invalidated invites' do
|
2022-08-04 22:20:48 -04:00
|
|
|
invite.update!(invalidated_at: 1.day.ago)
|
2021-03-25 12:26:22 -04:00
|
|
|
expect(invite.redeem).to be_blank
|
|
|
|
end
|
2015-03-25 12:55:18 -04:00
|
|
|
|
2021-03-25 12:26:22 -04:00
|
|
|
it 'deletes duplicate invite' do
|
|
|
|
another_invite = Fabricate(:invite, email: invite.email, invited_by: Fabricate(:user))
|
|
|
|
another_redeemed_invite = Fabricate(:invite, email: invite.email, invited_by: Fabricate(:user))
|
|
|
|
Fabricate(:invited_user, invite: another_redeemed_invite)
|
2015-03-25 12:55:18 -04:00
|
|
|
|
2021-03-25 12:26:22 -04:00
|
|
|
user = invite.redeem
|
|
|
|
expect(user).not_to eq(nil)
|
|
|
|
expect(Invite.find_by(id: another_invite.id)).to eq(nil)
|
|
|
|
expect(Invite.find_by(id: another_redeemed_invite.id)).not_to eq(nil)
|
2015-03-25 12:55:18 -04:00
|
|
|
end
|
|
|
|
|
2021-03-25 12:26:22 -04:00
|
|
|
context 'as a moderator' do
|
|
|
|
it 'will give the user a moderator flag' do
|
|
|
|
invite.update!(moderator: true, invited_by: Fabricate(:admin))
|
2016-09-20 13:12:00 -04:00
|
|
|
|
|
|
|
user = invite.redeem
|
|
|
|
expect(user).to be_moderator
|
|
|
|
end
|
|
|
|
|
2021-03-25 12:26:22 -04:00
|
|
|
it 'will not give the user a moderator flag if the inviter is not staff' do
|
|
|
|
invite.update!(moderator: true)
|
2016-09-20 13:12:00 -04:00
|
|
|
|
|
|
|
user = invite.redeem
|
|
|
|
expect(user).not_to be_moderator
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2021-03-25 12:26:22 -04:00
|
|
|
context 'when inviting to groups' do
|
|
|
|
it 'add the user to the correct groups' do
|
2014-05-08 02:45:49 -04:00
|
|
|
group = Fabricate(:group)
|
2020-06-15 05:13:56 -04:00
|
|
|
group.add_owner(invite.invited_by)
|
2021-03-25 12:26:22 -04:00
|
|
|
invite.invited_groups.create!(group_id: group.id)
|
2014-05-08 02:45:49 -04:00
|
|
|
|
|
|
|
user = invite.redeem
|
2021-03-25 12:26:22 -04:00
|
|
|
expect(user.groups).to contain_exactly(group)
|
2014-05-08 02:45:49 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2022-07-27 12:14:14 -04:00
|
|
|
context 'when inviting to a topic' do
|
2021-03-25 12:26:22 -04:00
|
|
|
fab!(:topic) { Fabricate(:private_message_topic) }
|
|
|
|
fab!(:another_topic) { Fabricate(:private_message_topic) }
|
2013-02-05 14:16:51 -05:00
|
|
|
|
2021-03-25 12:26:22 -04:00
|
|
|
before do
|
|
|
|
invite.topic_invites.create!(topic: topic)
|
2013-02-05 14:16:51 -05:00
|
|
|
end
|
|
|
|
|
2021-03-25 12:26:22 -04:00
|
|
|
it 'adds the user to topic_users' do
|
|
|
|
invited_user = invite.redeem
|
|
|
|
expect(invited_user).not_to eq(nil)
|
|
|
|
expect(topic.reload.allowed_users.include?(invited_user)).to eq(true)
|
|
|
|
expect(Guardian.new(invited_user).can_see?(topic)).to eq(true)
|
2013-02-05 14:16:51 -05:00
|
|
|
end
|
|
|
|
end
|
2021-03-25 12:26:22 -04:00
|
|
|
end
|
2013-02-05 14:16:51 -05:00
|
|
|
|
2022-11-01 12:33:32 -04:00
|
|
|
describe '#redeem_for_existing_user' do
|
2021-03-25 12:26:22 -04:00
|
|
|
fab!(:invite) { Fabricate(:invite, email: 'test@example.com') }
|
|
|
|
fab!(:user) { Fabricate(:user, email: invite.email) }
|
2014-05-08 21:45:18 -04:00
|
|
|
|
2021-03-25 12:26:22 -04:00
|
|
|
it 'redeems the invite from email' do
|
2022-11-01 12:33:32 -04:00
|
|
|
Invite.redeem_for_existing_user(user)
|
2021-03-25 12:26:22 -04:00
|
|
|
expect(invite.reload).to be_redeemed
|
2013-02-25 11:42:20 -05:00
|
|
|
end
|
2020-06-09 11:19:32 -04:00
|
|
|
|
2021-03-25 12:26:22 -04:00
|
|
|
it 'does not redeem the invite if email does not match' do
|
2022-11-01 12:33:32 -04:00
|
|
|
user.update!(email: 'test2@example.com')
|
|
|
|
Invite.redeem_for_existing_user(user)
|
2021-03-25 12:26:22 -04:00
|
|
|
expect(invite.reload).not_to be_redeemed
|
2020-06-09 11:19:32 -04:00
|
|
|
end
|
2022-08-04 22:20:48 -04:00
|
|
|
|
|
|
|
it 'does not work with expired invites' do
|
|
|
|
invite.update!(expires_at: 1.day.ago)
|
2022-11-01 12:33:32 -04:00
|
|
|
Invite.redeem_for_existing_user(user)
|
2022-08-04 22:20:48 -04:00
|
|
|
expect(invite).not_to be_redeemed
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'does not work with deleted invites' do
|
|
|
|
invite.trash!
|
2022-11-01 12:33:32 -04:00
|
|
|
Invite.redeem_for_existing_user(user)
|
2022-08-04 22:20:48 -04:00
|
|
|
expect(invite).not_to be_redeemed
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'does not work with invalidated invites' do
|
|
|
|
invite.update!(invalidated_at: 1.day.ago)
|
2022-11-01 12:33:32 -04:00
|
|
|
Invite.redeem_for_existing_user(user)
|
2022-08-04 22:20:48 -04:00
|
|
|
expect(invite).not_to be_redeemed
|
|
|
|
end
|
2013-02-05 14:16:51 -05:00
|
|
|
end
|
|
|
|
|
2022-07-27 12:14:14 -04:00
|
|
|
describe 'scopes' do
|
2021-03-25 12:26:22 -04:00
|
|
|
fab!(:inviter) { Fabricate(:user) }
|
2013-11-08 14:11:41 -05:00
|
|
|
|
2021-03-25 12:26:22 -04:00
|
|
|
fab!(:pending_invite) { Fabricate(:invite, invited_by: inviter, email: 'pending@example.com') }
|
2022-09-30 06:35:00 -04:00
|
|
|
fab!(:pending_link_invite) { Fabricate(:invite, invited_by: inviter, email: nil, max_redemptions_allowed: 5) }
|
2021-03-25 12:26:22 -04:00
|
|
|
fab!(:pending_invite_from_another_user) { Fabricate(:invite) }
|
2015-07-11 08:09:12 -04:00
|
|
|
|
2021-03-25 12:26:22 -04:00
|
|
|
fab!(:expired_invite) { Fabricate(:invite, invited_by: inviter, email: 'expired@example.com', expires_at: 1.day.ago) }
|
2015-07-11 08:09:12 -04:00
|
|
|
|
2021-03-25 12:26:22 -04:00
|
|
|
fab!(:redeemed_invite) { Fabricate(:invite, invited_by: inviter, email: 'redeemed@example.com') }
|
|
|
|
let!(:redeemed_invite_user) { redeemed_invite.redeem }
|
2017-11-14 05:38:54 -05:00
|
|
|
|
2021-03-25 12:26:22 -04:00
|
|
|
fab!(:partially_redeemed_invite) { Fabricate(:invite, invited_by: inviter, email: nil, max_redemptions_allowed: 5) }
|
|
|
|
let!(:partially_redeemed_invite_user) { partially_redeemed_invite.redeem(email: 'partially_redeemed_invite@example.com') }
|
2021-03-06 06:29:35 -05:00
|
|
|
|
2021-03-25 12:26:22 -04:00
|
|
|
fab!(:redeemed_and_expired_invite) { Fabricate(:invite, invited_by: inviter, email: 'redeemed_and_expired@example.com') }
|
|
|
|
let!(:redeemed_and_expired_invite_user) do
|
|
|
|
user = redeemed_and_expired_invite.redeem
|
|
|
|
redeemed_and_expired_invite.update!(expires_at: 1.day.ago)
|
|
|
|
user
|
2015-07-11 08:09:12 -04:00
|
|
|
end
|
2013-11-08 14:11:41 -05:00
|
|
|
|
2021-03-25 12:26:22 -04:00
|
|
|
fab!(:partially_redeemed_and_expired_invite) { Fabricate(:invite, invited_by: inviter, email: nil, max_redemptions_allowed: 5) }
|
|
|
|
let!(:partially_redeemed_and_expired_invite_user) do
|
|
|
|
user = partially_redeemed_and_expired_invite.redeem(email: 'partially_redeemed_and_expired_invite@example.com')
|
|
|
|
partially_redeemed_and_expired_invite.update!(expires_at: 1.day.ago)
|
|
|
|
user
|
2013-11-08 14:11:41 -05:00
|
|
|
end
|
2020-06-09 11:19:32 -04:00
|
|
|
|
2021-03-25 12:26:22 -04:00
|
|
|
describe '#pending' do
|
|
|
|
it 'returns pending invites only' do
|
|
|
|
expect(Invite.pending(inviter)).to contain_exactly(
|
|
|
|
pending_invite, pending_link_invite, partially_redeemed_invite
|
|
|
|
)
|
|
|
|
end
|
|
|
|
end
|
2021-03-06 06:29:35 -05:00
|
|
|
|
2021-03-25 12:26:22 -04:00
|
|
|
describe '#expired' do
|
|
|
|
it 'returns expired invites only' do
|
|
|
|
expect(Invite.expired(inviter)).to contain_exactly(
|
|
|
|
expired_invite, partially_redeemed_and_expired_invite
|
|
|
|
)
|
|
|
|
end
|
2021-03-06 06:29:35 -05:00
|
|
|
end
|
|
|
|
|
2021-03-25 12:26:22 -04:00
|
|
|
describe '#redeemed_users' do
|
|
|
|
it 'returns redeemed users' do
|
|
|
|
expect(Invite.redeemed_users(inviter).map(&:user)).to contain_exactly(
|
|
|
|
redeemed_invite_user, partially_redeemed_invite_user, redeemed_and_expired_invite_user, partially_redeemed_and_expired_invite_user
|
|
|
|
)
|
|
|
|
end
|
2020-06-09 11:19:32 -04:00
|
|
|
|
2021-03-25 12:26:22 -04:00
|
|
|
it 'returns redeemed users for trashed invites' do
|
|
|
|
[redeemed_invite, partially_redeemed_invite, redeemed_and_expired_invite, partially_redeemed_and_expired_invite].each(&:trash!)
|
2020-06-09 11:19:32 -04:00
|
|
|
|
2021-03-25 12:26:22 -04:00
|
|
|
expect(Invite.redeemed_users(inviter).map(&:user)).to contain_exactly(
|
|
|
|
redeemed_invite_user, partially_redeemed_invite_user, redeemed_and_expired_invite_user, partially_redeemed_and_expired_invite_user
|
|
|
|
)
|
|
|
|
end
|
2020-06-09 11:19:32 -04:00
|
|
|
end
|
2013-11-08 14:11:41 -05:00
|
|
|
end
|
2014-01-21 16:53:46 -05:00
|
|
|
|
2021-03-25 12:26:22 -04:00
|
|
|
describe '#invalidate_for_email' do
|
2014-01-21 16:53:46 -05:00
|
|
|
it 'returns nil if there is no invite for the given email' do
|
2021-03-25 12:26:22 -04:00
|
|
|
invite = Invite.invalidate_for_email('test@example.com')
|
|
|
|
expect(invite).to eq(nil)
|
2014-01-21 16:53:46 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'sets the matching invite to be invalid' do
|
2021-03-25 12:26:22 -04:00
|
|
|
invite = Fabricate(:invite, invited_by: Fabricate(:user), email: 'test@example.com')
|
|
|
|
result = Invite.invalidate_for_email('test@example.com')
|
2014-01-21 16:53:46 -05:00
|
|
|
|
2014-12-31 09:55:03 -05:00
|
|
|
expect(result).to eq(invite)
|
|
|
|
expect(result.link_valid?).to eq(false)
|
2014-01-21 16:53:46 -05:00
|
|
|
end
|
2014-07-04 15:53:41 -04:00
|
|
|
|
2021-03-25 12:26:22 -04:00
|
|
|
it 'sets the matching invite to be invalid without being case-sensitive' do
|
|
|
|
invite = Fabricate(:invite, invited_by: Fabricate(:user), email: 'test@Example.COM')
|
|
|
|
result = Invite.invalidate_for_email('test@EXAMPLE.com')
|
2014-07-04 15:53:41 -04:00
|
|
|
|
2021-03-25 12:26:22 -04:00
|
|
|
expect(result).to eq(invite)
|
|
|
|
expect(result.link_valid?).to eq(false)
|
2014-07-04 15:53:41 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2021-03-25 12:26:22 -04:00
|
|
|
describe '#resend_email' do
|
|
|
|
fab!(:invite) { Fabricate(:invite) }
|
2019-07-19 01:59:12 -04:00
|
|
|
|
2021-03-25 12:26:22 -04:00
|
|
|
it 'resets expiry of a resent invite' do
|
|
|
|
invite.update!(invalidated_at: 10.days.ago, expires_at: 10.days.ago)
|
|
|
|
expect(invite).to be_expired
|
2019-07-19 01:59:12 -04:00
|
|
|
|
2021-03-25 12:26:22 -04:00
|
|
|
invite.resend_invite
|
|
|
|
expect(invite).not_to be_expired
|
|
|
|
expect(invite.invalidated_at).to be_nil
|
2019-07-19 01:59:12 -04:00
|
|
|
end
|
|
|
|
end
|
2013-02-05 14:16:51 -05:00
|
|
|
end
|