<commit_before>require 'test_helper'
require 'model_tests_helper'

class InvitableTest < ActiveSupport::TestCase

  def setup
    setup_mailer
  end

  test 'should not generate invitation token after creating a record' do
    assert_nil new_user.invitation_token
  end

  test 'should not regenerate invitation token each time' do
    user = new_user
    user.invite!
    token = user.invitation_token
    assert_not_nil user.invitation_token
    assert_not_nil user.invitation_created_at
    3.times do
      user.invite!
      assert_equal token, user.invitation_token
    end
  end

  test 'should set invitation created and sent at each time' do
    user = new_user
    user.invite!
    old_invitation_created_at = 3.days.ago
    old_invitation_sent_at = 3.days.ago
    user.update_attributes(:invitation_sent_at => old_invitation_sent_at, :invitation_created_at => old_invitation_created_at)
    3.times do
      user.invite!
      assert_not_equal old_invitation_sent_at, user.invitation_sent_at
      assert_not_equal old_invitation_created_at, user.invitation_sent_at
      user.update_attributes(:invitation_sent_at => old_invitation_sent_at, :invitation_created_at => old_invitation_created_at)
    end
  end

  test 'should not regenerate invitation token even after the invitation token is not valid' do
    User.stubs(:invite_for).returns(1.day)
    user = new_user
    user.invite!
    token = user.invitation_token
    user.invitation_created_at = 3.days.ago
    user.save
    user.invite!
    assert_equal token, user.invitation_token
  end

  test 'should test invitation sent at with invite_for configuration value' do
    user = User.invite!(:email => "<EMAIL>")

    User.stubs(:invite_for).returns(nil)
    user.invitation_created_at = Time.now.utc
    assert user.valid_invitation?

    User.stubs(:invite_for).returns(nil)
    user.invitation_created_at = 1.year.ago
    assert user.valid_invitation?

    User.stubs(:invite_for).returns(0)
    user.invitation_created_at = Time.now.utc
    assert user.valid_invitation?

    User.stubs(:invite_for).returns(0)
    user.invitation_created_at = 1.day.ago
    assert user.valid_invitation?

    User.stubs(:invite_for).returns(1.day)
    user.invitation_created_at = Time.now.utc
    assert user.valid_invitation?

    User.stubs(:invite_for).returns(1.day)
    user.invitation_created_at = 2.days.ago
    assert !user.valid_invitation?
  end

  test 'should never generate the same invitation token for different users' do
    invitation_tokens = []
    3.times do
      user = new_user
      user.invite!
      token = user.invitation_token
      assert !invitation_tokens.include?(token)
      invitation_tokens << token
    end
  end

  test 'should invite with mutiple columns for invite key' do
    User.stubs(:invite_key).returns(:email => Devise.email_regexp, :username => /\A.+\z/)
    user = User.invite!(:email => "<EMAIL>", :username => "name")
    assert user.persisted?
    assert user.errors.empty?
  end

  test 'should not invite with some missing columns when invite key is an array' do
    User.stubs(:invite_key).returns(:email => Devise.email_regexp, :username => /\A.+\z/)
    user = User.invite!(:email => "<EMAIL>")
    assert user.new_record?
    assert user.errors.present?
  end

  test 'should return mail object' do
    mail = User.invite_mail!(:email => '<EMAIL>')
    assert mail.class.name == 'Mail::Message'
  end

  test 'should disallow login when invited' do
    invited_user = User.invite!(:email => "<EMAIL>")
    assert !invited_user.valid_password?('<PASSWORD>')
  end

  test 'should set password and password confirmation from params' do
    invited_user = User.invite!(:email => "<EMAIL>")
    user = User.accept_invitation!(:invitation_token => invited_user.invitation_token, :password => '<PASSWORD>', :password_confirmation => '<PASSWORD>')
    assert user.valid_password?('<PASSWORD>')
  end

  test 'should set password and save the record' do
    user = User.invite!(:email => "<EMAIL>")
    old_encrypted_password = user.encrypted_password
    user = User.accept_invitation!(:invitation_token => user.invitation_token, :password => '<PASSWORD>', :password_confirmation => '<PASSWORD>')
    assert_not_equal old_encrypted_password, user.encrypted_password
  end

  test 'should clear invitation token and set invitation_accepted_at while accepting the password' do
    user = User.invite!(:email => "<EMAIL>")
    assert_present user.invitation_token
    assert_nil user.invitation_accepted_at
    user.accept_invitation!
    user.reload
    assert_nil user.invitation_token
    assert_present user.invitation_accepted_at
  end

  test 'should not clear invitation token or set accepted_at if record is invalid' do
    user = User.invite!(:email => "<EMAIL>")
    assert_present user.invitation_token
    assert_nil user.invitation_accepted_at
    User.accept_invitation!(:invitation_token => user.invitation_token, :password => '<PASSWORD>', :password_confirmation => '<PASSWORD>')
    user.reload
    assert_present user.invitation_token
    assert_nil user.invitation_accepted_at
  end

  test 'should clear invitation token while resetting the password' do
    user = User.invite!(:email => "<EMAIL>")
    assert user.invited_to_sign_up?
    user.send(:generate_reset_password_token!)
    assert_present user.reset_password_token
    assert_present user.invitation_token
    User.reset_password_by_token(:reset_password_token => user.reset_password_token, :password => '<PASSWORD>', :password_confirmation => '<PASSWORD>')
    assert_nil user.reload.invitation_token
    assert !user.invited_to_sign_up?
  end

  test 'should not accept invitation on failing to reset the password' do
    user = User.invite!(:email => "<EMAIL>")
    assert user.invited_to_sign_up?
    user.send(:generate_reset_password_token!)
    assert_present user.reset_password_token
    assert_present user.invitation_token
    User.reset_password_by_token(:reset_password_token => user.reset_password_token, :password => '<PASSWORD>', :password_confirmation => '<PASSWORD>')
    assert_present user.reload.invitation_token
    assert user.invited_to_sign_up?
  end

  test 'should not set invitation_accepted_at if just resetting password' do
    user = User.create!(:email => "<EMAIL>", :password => "<PASSWORD>")
    assert !user.invited_to_sign_up?
    user.send(:generate_reset_password_token!)
    assert_present user.reset_password_token
    assert_nil user.invitation_token
    User.reset_password_by_token(:reset_password_token => user.reset_password_token, :password => '<PASSWORD>', :password_confirmation => '<PASSWORD>')
    assert_nil user.reload.invitation_token
    assert_nil user.reload.invitation_accepted_at
  end

  test 'should reset invitation token and send invitation by email' do
    user = new_user
    assert_difference('ActionMailer::Base.deliveries.size') do
      token = user.invitation_token
      user.invite!
      assert_not_equal token, user.invitation_token
    end
  end

  test 'should return a record with invitation token and no errors to send invitation by email' do
    invited_user = User.invite!(:email => "<EMAIL>")
    assert invited_user.errors.blank?
    assert_present invited_user.invitation_token
    assert_equal '<EMAIL>', invited_user.email
    assert invited_user.persisted?
  end

  test 'should set all attributes with no errors' do
    invited_user = User.invite!(:email => "<EMAIL>", :username => 'first name')
    assert invited_user.errors.blank?
    assert_equal 'first name', invited_user.username
    assert invited_user.persisted?
  end

  test 'should not validate other attributes when validate_on_invite is disabled' do
    validate_on_invite = User.validate_on_invite
    User.validate_on_invite = false
    invited_user = User.invite!(:email => "<EMAIL>", :username => "a"*50)
    assert invited_user.errors.empty?
    User.validate_on_invite = validate_on_invite
  end

  test 'should validate other attributes when validate_on_invite is enabled' do
    validate_on_invite = User.validate_on_invite
    User.validate_on_invite = true
    invited_user = User.invite!(:email => "<EMAIL>", :username => "a"*50)
    assert invited_user.errors[:username].present?
    User.validate_on_invite = validate_on_invite
  end

  test 'should not validate password when validate_on_invite is enabled' do
    validate_on_invite = User.validate_on_invite
    User.validate_on_invite = true
    invited_user = User.invite!(:email => "<EMAIL>", :username => "a"*50)
    assert invited_user.errors.present?
    assert invited_user.errors[:password].empty?
    User.validate_on_invite = validate_on_invite
  end

  test 'should validate other attributes when validate_on_invite is enabled and email is not present' do
    validate_on_invite = User.validate_on_invite
    User.validate_on_invite = true
    invited_user = User.invite!(:email => "", :username => "a"*50)
    assert invited_user.errors[:email].present?
    assert invited_user.errors[:username].present?
    User.validate_on_invite = validate_on_invite
  end

  test 'should return a record with errors if user was found by e-mail' do
    existing_user = User.new(:email => "<EMAIL>")
    existing_user.save(:validate => false)
    user = User.invite!(:email => "<EMAIL>")
    assert_equal user, existing_user
    assert_equal ['has already been taken'], user.errors[:email]
  end

  test 'should return a record with errors if user with pending invitation was found by e-mail' do
    existing_user = User.invite!(:email => "<EMAIL>")
    user = User.invite!(:email => "<EMAIL>")
    assert_equal user, existing_user
    assert_equal [], user.errors[:email]
    resend_invitation = User.resend_invitation
    begin
      User.resend_invitation = false

      user = User.invite!(:email => "<EMAIL>")
      assert_equal user, existing_user
      assert_equal ['has already been taken'], user.errors[:email]
    ensure
      User.resend_invitation = resend_invitation<commit_msg>test for issue #361 - shouldnot allow user with same email to persist<commit_after>require 'test_helper'
require 'model_tests_helper'

class InvitableTest < ActiveSupport::TestCase

  def setup
    setup_mailer
  end

  test 'should not generate invitation token after creating a record' do
    assert_nil new_user.invitation_token
  end

  test 'should not regenerate invitation token each time' do
    user = new_user
    user.invite!
    token = user.invitation_token
    assert_not_nil user.invitation_token
    assert_not_nil user.invitation_created_at
    3.times do
      user.invite!
      assert_equal token, user.invitation_token
    end
  end

  test 'should set invitation created and sent at each time' do
    user = new_user
    user.invite!
    old_invitation_created_at = 3.days.ago
    old_invitation_sent_at = 3.days.ago
    user.update_attributes(:invitation_sent_at => old_invitation_sent_at, :invitation_created_at => old_invitation_created_at)
    3.times do
      user.invite!
      assert_not_equal old_invitation_sent_at, user.invitation_sent_at
      assert_not_equal old_invitation_created_at, user.invitation_sent_at
      user.update_attributes(:invitation_sent_at => old_invitation_sent_at, :invitation_created_at => old_invitation_created_at)
    end
  end

  test 'should not regenerate invitation token even after the invitation token is not valid' do
    User.stubs(:invite_for).returns(1.day)
    user = new_user
    user.invite!
    token = user.invitation_token
    user.invitation_created_at = 3.days.ago
    user.save
    user.invite!
    assert_equal token, user.invitation_token
  end

  test 'should test invitation sent at with invite_for configuration value' do
    user = User.invite!(:email => "<EMAIL>")

    User.stubs(:invite_for).returns(nil)
    user.invitation_created_at = Time.now.utc
    assert user.valid_invitation?

    User.stubs(:invite_for).returns(nil)
    user.invitation_created_at = 1.year.ago
    assert user.valid_invitation?

    User.stubs(:invite_for).returns(0)
    user.invitation_created_at = Time.now.utc
    assert user.valid_invitation?

    User.stubs(:invite_for).returns(0)
    user.invitation_created_at = 1.day.ago
    assert user.valid_invitation?

    User.stubs(:invite_for).returns(1.day)
    user.invitation_created_at = Time.now.utc
    assert user.valid_invitation?

    User.stubs(:invite_for).returns(1.day)
    user.invitation_created_at = 2.days.ago
    assert !user.valid_invitation?
  end

  test 'should never generate the same invitation token for different users' do
    invitation_tokens = []
    3.times do
      user = new_user
      user.invite!
      token = user.invitation_token
      assert !invitation_tokens.include?(token)
      invitation_tokens << token
    end
  end

  test 'should invite with mutiple columns for invite key' do
    User.stubs(:invite_key).returns(:email => Devise.email_regexp, :username => /\A.+\z/)
    user = User.invite!(:email => "<EMAIL>", :username => "name")
    assert user.persisted?
    assert user.errors.empty?
  end

  test 'should not invite with some missing columns when invite key is an array' do
    User.stubs(:invite_key).returns(:email => Devise.email_regexp, :username => /\A.+\z/)
    user = User.invite!(:email => "<EMAIL>")
    assert user.new_record?
    assert user.errors.present?
  end

  test 'should return mail object' do
    mail = User.invite_mail!(:email => '<EMAIL>')
    assert mail.class.name == 'Mail::Message'
  end

  test 'should disallow login when invited' do
    invited_user = User.invite!(:email => "<EMAIL>")
    assert !invited_user.valid_password?('<PASSWORD>')
  end

  test 'should set password and password confirmation from params' do
    invited_user = User.invite!(:email => "<EMAIL>")
    user = User.accept_invitation!(:invitation_token => invited_user.invitation_token, :password => '<PASSWORD>', :password_confirmation => '<PASSWORD>')
    assert user.valid_password?('<PASSWORD>')
  end

  test 'should set password and save the record' do
    user = User.invite!(:email => "<EMAIL>")
    old_encrypted_password = user.encrypted_password
    user = User.accept_invitation!(:invitation_token => user.invitation_token, :password => '<PASSWORD>', :password_confirmation => '<PASSWORD>')
    assert_not_equal old_encrypted_password, user.encrypted_password
  end

  test 'should clear invitation token and set invitation_accepted_at while accepting the password' do
    user = User.invite!(:email => "<EMAIL>")
    assert_present user.invitation_token
    assert_nil user.invitation_accepted_at
    user.accept_invitation!
    user.reload
    assert_nil user.invitation_token
    assert_present user.invitation_accepted_at
  end

  test 'should not clear invitation token or set accepted_at if record is invalid' do
    user = User.invite!(:email => "<EMAIL>")
    assert_present user.invitation_token
    assert_nil user.invitation_accepted_at
    User.accept_invitation!(:invitation_token => user.invitation_token, :password => '<PASSWORD>', :password_confirmation => '<PASSWORD>')
    user.reload
    assert_present user.invitation_token
    assert_nil user.invitation_accepted_at
  end

  test 'should clear invitation token while resetting the password' do
    user = User.invite!(:email => "<EMAIL>")
    assert user.invited_to_sign_up?
    user.send(:generate_reset_password_token!)
    assert_present user.reset_password_token
    assert_present user.invitation_token
    User.reset_password_by_token(:reset_password_token => user.reset_password_token, :password => '<PASSWORD>', :password_confirmation => '<PASSWORD>')
    assert_nil user.reload.invitation_token
    assert !user.invited_to_sign_up?
  end

  test 'should not accept invitation on failing to reset the password' do
    user = User.invite!(:email => "<EMAIL>")
    assert user.invited_to_sign_up?
    user.send(:generate_reset_password_token!)
    assert_present user.reset_password_token
    assert_present user.invitation_token
    User.reset_password_by_token(:reset_password_token => user.reset_password_token, :password => '<PASSWORD>', :password_confirmation => '<PASSWORD>')
    assert_present user.reload.invitation_token
    assert user.invited_to_sign_up?
  end

  test 'should not set invitation_accepted_at if just resetting password' do
    user = User.create!(:email => "<EMAIL>", :password => "<PASSWORD>")
    assert !user.invited_to_sign_up?
    user.send(:generate_reset_password_token!)
    assert_present user.reset_password_token
    assert_nil user.invitation_token
    User.reset_password_by_token(:reset_password_token => <PASSWORD>.reset_password_token, :password => '<PASSWORD>', :password_confirmation => '<PASSWORD>')
    assert_nil user.reload.invitation_token
    assert_nil user.reload.invitation_accepted_at
  end

  test 'should reset invitation token and send invitation by email' do
    user = new_user
    assert_difference('ActionMailer::Base.deliveries.size') do
      token = user.invitation_token
      user.invite!
      assert_not_equal token, user.invitation_token
    end
  end

  test 'should return a record with invitation token and no errors to send invitation by email' do
    invited_user = User.invite!(:email => "<EMAIL>")
    assert invited_user.errors.blank?
    assert_present invited_user.invitation_token
    assert_equal '<EMAIL>', invited_user.email
    assert invited_user.persisted?
  end

  test 'should set all attributes with no errors' do
    invited_user = User.invite!(:email => "<EMAIL>", :username => 'first name')
    assert invited_user.errors.blank?
    assert_equal 'first name', invited_user.username
    assert invited_user.persisted?
  end

  test 'should not validate other attributes when validate_on_invite is disabled' do
    validate_on_invite = User.validate_on_invite
    User.validate_on_invite = false
    invited_user = User.invite!(:email => "<EMAIL>", :username => "a"*50)
    assert invited_user.errors.empty?
    User.validate_on_invite = validate_on_invite
  end

  test 'should validate other attributes when validate_on_invite is enabled' do
    validate_on_invite = User.validate_on_invite
    User.validate_on_invite = true
    invited_user = User.invite!(:email => "<EMAIL>", :username => "a"*50)
    assert invited_user.errors[:username].present?
    User.validate_on_invite = validate_on_invite
  end

  test 'should not validate password when validate_on_invite is enabled' do
    validate_on_invite = User.validate_on_invite
    User.validate_on_invite = true
    invited_user = User.invite!(:email => "<EMAIL>", :username => "a"*50)
    assert invited_user.errors.present?
    assert invited_user.errors[:password].empty?
    User.validate_on_invite = validate_on_invite
  end

  test 'should validate other attributes when validate_on_invite is enabled and email is not present' do
    validate_on_invite = User.validate_on_invite
    User.validate_on_invite = true
    invited_user = User.invite!(:email => "", :username => "a"*50)
    assert invited_user.errors[:email].present?
    assert invited_user.errors[:username].present?
    User.validate_on_invite = validate_on_invite
  end

  test 'should return a record with errors if user was found by e-mail' do
    existing_user = User.new(:email => "<EMAIL>")
    existing_user.save(:validate => false)
    user = User.invite!(:email => "<EMAIL>")
    assert_equal user, existing_user
    assert_equal ['has already been taken'], user.errors[:email]
    same_user = User.invite!("email" => "<EMAIL>")
    assert_equal same_user, existing_user
    assert_equal ['has already been taken'], same_user.errors[:email]
  end

  test 'should return a record with errors if user with pending invitation was found by e-mail' do
    existing_user = User.invite!(:email => "<EMAIL>")
    user = User.invite!(:email => "<EMAIL>")
    assert_equal user, existing_user
    assert_equal [], user.errors[:email]
    resend_invitation = User.resend_invitation
    begin
      User.resend_invitation = false

      user = User.invite!(:email => "<EMAIL>")
      assert_equal user, existing_user
      assert_equal ['has already been taken'], user.errors[:email]
    ensure
      User.resend_invitation = resend_invitation
{'fraction_non_alphanumeric': 0.09631461785802622, 'fraction_numerical': 0.002325006183527084, 'mean_word_length': 4.207624935600206, 'pattern_counts': {'":': 0, '<': 87, '<?xml version=': 0, '>': 196, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5191126', 'n_tokens_mistral': 6229, 'n_tokens_neox': 6201, 'n_words': 1486}