discourse/spec/models/invite_spec.rb
Luciano Sousa b3d769ff4f Update rspec syntax to v3
update rspec syntax to v3

change syntax to rspec v3

oops. fix typo

mailers classes with rspec3 syntax

helpers with rspec3 syntax

jobs with rspec3 syntax

serializers with rspec3 syntax

views with rspec3 syntax

support to rspec3 syntax

category spec with rspec3 syntax
2015-01-05 11:59:30 -03:00

436 lines
13 KiB
Ruby

require 'spec_helper'
describe Invite do
it { is_expected.to validate_presence_of :invited_by_id }
let(:iceking) { 'iceking@adventuretime.ooo' }
context 'user validators' do
let(:coding_horror) { Fabricate(:coding_horror) }
let(:user) { Fabricate(:user) }
let(:invite) { Invite.create(email: user.email, invited_by: coding_horror) }
it "should not allow an invite with the same email as an existing user" do
expect(invite).not_to be_valid
end
it "should not allow a user to invite themselves" do
expect(invite.email_already_exists).to eq(true)
end
end
context 'email validators' do
let(:coding_horror) { Fabricate(:coding_horror) }
let(:invite) { Invite.create(email: "test@mailinator.com", invited_by: coding_horror) }
it "should not allow an invite with blacklisted email" do
expect(invite).not_to be_valid
end
it "should allow an invite with non-blacklisted email" do
invite = Fabricate(:invite, email: "test@mail.com", invited_by: coding_horror)
expect(invite).to be_valid
end
end
context '#create' do
context 'saved' do
subject { Fabricate(:invite) }
it "works" do
expect(subject.invite_key).to be_present
expect(subject.email_already_exists).to eq(false)
end
it 'should store a lower case version of the email' do
expect(subject.email).to eq(iceking)
end
end
context 'to a topic' do
let!(:topic) { Fabricate(:topic) }
let(:inviter) { topic.user }
context 'email' do
it 'enqueues a job to email the invite' do
Jobs.expects(:enqueue).with(:invite_email, has_key(:invite_id))
topic.invite_by_email(inviter, iceking)
end
end
context 'destroyed' do
it "can invite the same user after their invite was destroyed" do
invite = topic.invite_by_email(inviter, iceking)
invite.destroy
invite = topic.invite_by_email(inviter, iceking)
expect(invite).to be_present
end
end
context 'after created' do
before do
@invite = topic.invite_by_email(inviter, iceking)
end
it 'belongs to the topic' do
expect(topic.invites).to eq([@invite])
expect(@invite.topics).to eq([topic])
end
context 'when added by another user' do
let(:coding_horror) { Fabricate(:coding_horror) }
let(:new_invite) { topic.invite_by_email(coding_horror, iceking) }
it 'returns a different invite' do
expect(new_invite).not_to eq(@invite)
expect(new_invite.invite_key).not_to eq(@invite.invite_key)
expect(new_invite.topics).to eq([topic])
end
end
context 'when adding a duplicate' do
it 'returns the original invite' do
expect(topic.invite_by_email(inviter, 'iceking@adventuretime.ooo')).to eq(@invite)
expect(topic.invite_by_email(inviter, 'iceking@ADVENTURETIME.ooo')).to eq(@invite)
expect(topic.invite_by_email(inviter, 'ICEKING@adventuretime.ooo')).to eq(@invite)
end
it 'returns a new invite if the other has expired' do
SiteSetting.stubs(:invite_expiry_days).returns(1)
@invite.created_at = 2.days.ago
@invite.save
new_invite = topic.invite_by_email(inviter, 'iceking@adventuretime.ooo')
expect(new_invite).not_to eq(@invite)
expect(new_invite).not_to be_expired
end
end
context 'when adding to another topic' do
let!(:another_topic) { Fabricate(:topic, user: topic.user) }
it 'should be the same invite' do
@new_invite = another_topic.invite_by_email(inviter, iceking)
expect(@new_invite).to eq(@invite)
expect(another_topic.invites).to eq([@invite])
expect(@invite.topics).to match_array([topic, another_topic])
end
end
end
end
end
context 'an existing user' do
let(:topic) { Fabricate(:topic, category_id: nil, archetype: 'private_message') }
let(:coding_horror) { Fabricate(:coding_horror) }
let!(:invite) { topic.invite_by_email(topic.user, coding_horror.email) }
it "works" do
# doesn't create an invite
expect(invite).to be_blank
# gives the user permission to access the topic
expect(topic.allowed_users.include?(coding_horror)).to eq(true)
end
end
context '.redeem' do
let(:invite) { Fabricate(:invite) }
it 'creates a notification for the invitee' do
expect { invite.redeem }.to change(Notification, :count)
end
it 'wont redeem an expired invite' do
SiteSetting.expects(:invite_expiry_days).returns(10)
invite.update_column(:created_at, 20.days.ago)
expect(invite.redeem).to be_blank
end
it 'wont redeem a deleted invite' do
invite.destroy
expect(invite.redeem).to be_blank
end
it "won't redeem an invalidated invite" do
invite.invalidated_at = 1.day.ago
expect(invite.redeem).to be_blank
end
context 'enqueues a job to email "set password" instructions' do
it 'does not enqueue an email if sso is enabled' do
SiteSetting.stubs(:enable_sso).returns(true)
Jobs.expects(:enqueue).with(:invite_password_instructions_email, has_key(:username)).never
invite.redeem
end
it 'does not enqueue an email if local login is disabled' do
SiteSetting.stubs(:enable_local_logins).returns(false)
Jobs.expects(:enqueue).with(:invite_password_instructions_email, has_key(:username)).never
invite.redeem
end
it 'does not enqueue an email if the user has already set password' do
user = Fabricate(:user, email: invite.email, password_hash: "7af7805c9ee3697ed1a83d5e3cb5a3a431d140933a87fdcdc5a42aeef9337f81")
Jobs.expects(:enqueue).with(:invite_password_instructions_email, has_key(:username)).never
invite.redeem
end
it 'enqueues an email if all conditions are satisfied' do
Jobs.expects(:enqueue).with(:invite_password_instructions_email, has_key(:username))
invite.redeem
end
end
context "when inviting to groups" do
it "add the user to the correct groups" do
group = Fabricate(:group)
invite.invited_groups.build(group_id: group.id)
invite.save
user = invite.redeem
expect(user.groups.count).to eq(1)
end
end
context "invite trust levels" do
it "returns the trust level in default_invitee_trust_level" do
SiteSetting.stubs(:default_invitee_trust_level).returns(TrustLevel[3])
expect(invite.redeem.trust_level).to eq(TrustLevel[3])
end
end
context 'inviting when must_approve_users? is enabled' do
it 'correctly activates accounts' do
SiteSetting.stubs(:must_approve_users).returns(true)
user = invite.redeem
expect(user.approved?).to eq(true)
end
end
context 'simple invite' do
let!(:user) { invite.redeem }
it 'works correctly' do
expect(user.is_a?(User)).to eq(true)
expect(user.send_welcome_message).to eq(true)
expect(user.trust_level).to eq(SiteSetting.default_invitee_trust_level)
end
context 'after redeeming' do
before do
invite.reload
end
it 'works correctly' do
# has set the user_id attribute
expect(invite.user).to eq(user)
# returns true for redeemed
expect(invite).to be_redeemed
end
context 'again' do
context "without a passthrough" do
before do
SiteSetting.invite_passthrough_hours = 0
end
it 'will not redeem twice' do
expect(invite.redeem).to be_blank
end
end
context "with a passthrough" do
before do
SiteSetting.invite_passthrough_hours = 1
end
it 'will not redeem twice' do
expect(invite.redeem).to be_present
expect(invite.redeem.send_welcome_message).to eq(false)
end
end
end
end
end
context 'invited to topics' do
let!(:topic) { Fabricate(:private_message_topic) }
let!(:invite) {
topic.invite(topic.user, 'jake@adventuretime.ooo')
}
context 'redeem topic invite' do
it 'adds the user to the topic_users' do
user = invite.redeem
topic.reload
expect(topic.allowed_users.include?(user)).to eq(true)
expect(Guardian.new(user).can_see?(topic)).to eq(true)
end
end
context 'invited by another user to the same topic' do
let(:coding_horror) { User.find_by(username: "CodingHorror") }
let!(:another_invite) { topic.invite(coding_horror, 'jake@adventuretime.ooo') }
let!(:user) { invite.redeem }
it 'adds the user to the topic_users' do
topic.reload
expect(topic.allowed_users.include?(user)).to eq(true)
end
end
context 'invited by another user to a different topic' do
let!(:another_invite) { another_topic.invite(coding_horror, 'jake@adventuretime.ooo') }
let!(:user) { invite.redeem }
let(:coding_horror) { User.find_by(username: "CodingHorror") }
let(:another_topic) { Fabricate(:topic, category_id: nil, archetype: "private_message", user: coding_horror) }
it 'adds the user to the topic_users of the first topic' do
expect(topic.allowed_users.include?(user)).to eq(true)
expect(another_topic.allowed_users.include?(user)).to eq(true)
another_invite.reload
expect(another_invite).not_to be_redeemed
end
context 'if they redeem the other invite afterwards' do
it 'returns the same user' do
result = another_invite.redeem
expect(result).to eq(user)
another_invite.reload
expect(another_invite).to be_redeemed
end
end
end
end
end
describe '.find_all_invites_from' do
context 'with user that has invited' do
it 'returns invites' do
inviter = Fabricate(:user)
invite = Fabricate(:invite, invited_by: inviter)
invites = Invite.find_all_invites_from(inviter)
expect(invites).to include invite
end
end
context 'with user that has not invited' do
it 'does not return invites' do
user = Fabricate(:user)
Fabricate(:invite)
invites = Invite.find_all_invites_from(user)
expect(invites).to be_empty
end
end
end
describe '.find_redeemed_invites_from' do
it 'returns redeemed invites only' do
inviter = Fabricate(:user)
Fabricate(
:invite,
invited_by: inviter,
user_id: nil,
email: 'pending@example.com'
)
redeemed_invite = Fabricate(
:invite,
invited_by: inviter,
user_id: 123,
email: 'redeemed@example.com'
)
invites = Invite.find_redeemed_invites_from(inviter)
expect(invites.size).to eq(1)
expect(invites.first).to eq redeemed_invite
end
end
describe '.invalidate_for_email' do
let(:email) { 'invite.me@example.com' }
subject { described_class.invalidate_for_email(email) }
it 'returns nil if there is no invite for the given email' do
expect(subject).to eq(nil)
end
it 'sets the matching invite to be invalid' do
invite = Fabricate(:invite, invited_by: Fabricate(:user), user_id: nil, email: email)
expect(subject).to eq(invite)
expect(subject.link_valid?).to eq(false)
expect(subject).to be_valid
end
it 'sets the matching invite to be invalid without being case-sensitive' do
invite = Fabricate(:invite, invited_by: Fabricate(:user), user_id: nil, email: 'invite.me2@Example.COM')
result = described_class.invalidate_for_email('invite.me2@EXAMPLE.com')
expect(result).to eq(invite)
expect(result.link_valid?).to eq(false)
expect(result).to be_valid
end
end
describe '.redeem_from_email' do
let(:inviter) { Fabricate(:user) }
let(:invite) { Fabricate(:invite, invited_by: inviter, email: 'test@example.com', user_id: nil) }
let(:user) { Fabricate(:user, email: invite.email) }
it 'redeems the invite from email' do
result = Invite.redeem_from_email(user.email)
invite.reload
expect(invite).to be_redeemed
end
it 'does not redeem the invite if email does not match' do
result = Invite.redeem_from_email('test24@example.com')
invite.reload
expect(invite).not_to be_redeemed
end
end
describe '.redeem_from_token' do
let(:inviter) { Fabricate(:user) }
let(:invite) { Fabricate(:invite, invited_by: inviter, email: 'test@example.com', user_id: nil) }
let(:user) { Fabricate(:user, email: invite.email) }
it 'redeems the invite from token' do
result = Invite.redeem_from_token(invite.invite_key, user.email)
invite.reload
expect(invite).to be_redeemed
end
it 'does not redeem the invite if token does not match' do
result = Invite.redeem_from_token("bae0071f995bb4b6f756e80b383778b5", user.email)
invite.reload
expect(invite).not_to be_redeemed
end
end
end