diff --git a/app/controllers/invitations_controller.rb b/app/controllers/invitations_controller.rb index 89c774ffd..512be9b48 100644 --- a/app/controllers/invitations_controller.rb +++ b/app/controllers/invitations_controller.rb @@ -34,7 +34,7 @@ class InvitationsController < Devise::InvitationsController begin invitation_token = params[:user][:invitation_token] if invitation_token.nil? || invitation_token.blank? - raise "Invalid Invite Token" + raise I18n.t('invitations.check_token.not_found') end user = User.find_by_invitation_token(params[:user][:invitation_token]) user.seed_aspects diff --git a/app/models/invitation.rb b/app/models/invitation.rb index bfdcb0dcb..dc98f9d39 100644 --- a/app/models/invitation.rb +++ b/app/models/invitation.rb @@ -28,34 +28,44 @@ class Invitation create_invitee(opts) end + def self.new_or_existing_user_by_email(email) + existing_user = User.first(:email => email) + if existing_user + existing_user + else + result = User.new() + result.email = email + result.valid? + result + end + end + def self.create_invitee(opts = {}) - invitee = User.find_or_initialize_with_error_by(:email, opts[:email]) + invitee = new_or_existing_user_by_email(opts[:email]) + return invitee unless opts[:email].match Devise.email_regexp invitee.invites = opts[:invites] if invitee.new_record? - invitee.errors.clear if invitee.email.try(:match, Devise.email_regexp) - else - invitee.errors.add(:email, :taken) unless invitee.invited? - end - - if invitee.errors.empty? - - if opts[:from] - invitee.save(:validate => false) - Invitation.create!(:from => opts[:from], - :to => invitee, - :into => opts[:into], - :message => opts[:message]) - - opts[:from].invites -= 1 unless opts[:from].invites == 0 - opts[:from].save! - invitee.reload - end - + invitee.errors.clear invitee.serialized_private_key ||= User.generate_key invitee.send(:generate_invitation_token) - invitee.invite! - Rails.logger.info("event=invitation_sent to=#{opts[:email]} #{"inviter=#{opts[:from].diaspora_handle}" if opts[:from]}") + elsif invitee.invitation_token.nil? + return invitee end + + if opts[:from] + invitee.save(:validate => false) + Invitation.create!(:from => opts[:from], + :to => invitee, + :into => opts[:into], + :message => opts[:message]) + + opts[:from].invites -= 1 unless opts[:from].invites == 0 + opts[:from].save! + invitee.reload + end + + invitee.invite! + Rails.logger.info("event=invitation_sent to=#{opts[:email]} #{"inviter=#{opts[:from].diaspora_handle}" if opts[:from]}") invitee end diff --git a/spec/models/invitation_spec.rb b/spec/models/invitation_spec.rb index 20329da34..68d129c0c 100644 --- a/spec/models/invitation_spec.rb +++ b/spec/models/invitation_spec.rb @@ -43,6 +43,28 @@ describe Invitation do @invitation.message.should == "!" end + describe '.new_or_existing_user_by_email' do + let(:inv){Invitation.new_or_existing_user_by_email(@email)} + before do + @users = [] + 8.times do + @users << make_user + end + end + it 'returns User.new for a non-existent user' do + @email = "maggie@example.org" + inv.email.should == @email + inv.persisted?.should be_false + lambda { + inv.reload + }.should raise_error /does not exist/ + end + it 'returns an existing user' do + @email = @users[3].email + inv.should == @users[3] + end + end + describe '.invite' do it 'creates an invitation' do lambda { @@ -110,7 +132,6 @@ describe Invitation do end context 'invalid email' do - it 'return a user with errors' do new_user = Invitation.invite(:email => "fkjlsdf", :from => user, :into => aspect) new_user.should have(1).errors_on(:email) @@ -120,6 +141,36 @@ describe Invitation do end describe '.create_invitee' do + context 'with an existing invitee' do + before do + @valid_params = {:from => user, + :email => @email, + :into => aspect, + :message => @message} + @invitee = Invitation.create_invitee(:email => @email) + end + it 'creates no user' do + lambda { + Invitation.create_invitee(@valid_params) + }.should_not change(User, :count) + end + it 'sends mail' do + lambda { + Invitation.create_invitee(@valid_params) + }.should change{Devise.mailer.deliveries.size}.by(1) + end + it 'does not set the key' do + lambda { + Invitation.create_invitee(@valid_params) + }.should_not change{@invitee.reload.serialized_private_key} + end + it 'does not change the invitation token' do + pending "until this passes, old invitation emails will be invalidated by new ones" + lambda { + Invitation.create_invitee(@valid_params) + }.should_not change{@invitee.reload.invitation_token} + end + end context 'with an inviter' do before do @message = "whatever"