cartodb-4.42/spec/models/carto/user_creation_spec.rb
2024-04-06 05:25:13 +00:00

511 lines
22 KiB
Ruby

require_relative '../../spec_helper'
require_relative '../../../app/models/carto/user_creation'
describe Carto::UserCreation do
describe 'autologin?' do
it 'is true for autologin_user_creation factory' do
FactoryGirl.build(:autologin_user_creation).autologin?.should == true
end
it 'is false for states other than success' do
FactoryGirl.build(:autologin_user_creation, state: 'creating_user').autologin?.should == false
FactoryGirl.build(:autologin_user_creation, state: 'validating_user').autologin?.should == false
FactoryGirl.build(:autologin_user_creation, state: 'saving_user').autologin?.should == false
FactoryGirl.build(:autologin_user_creation, state: 'promoting_user').autologin?.should == false
FactoryGirl.build(:autologin_user_creation, state: 'creating_user_in_central').autologin?.should == false
FactoryGirl.build(:autologin_user_creation, state: 'load_common_data').autologin?.should == false
FactoryGirl.build(:autologin_user_creation, state: 'failure').autologin?.should == false
FactoryGirl.build(:autologin_user_creation, state: 'success').autologin?.should == true
end
it 'is stops working after one minute' do
FactoryGirl.build(:autologin_user_creation, created_at: Time.now - 61.seconds).autologin?.should == false
FactoryGirl.build(:autologin_user_creation, created_at: Time.now - 60.seconds).autologin?.should == false
FactoryGirl.build(:autologin_user_creation, created_at: Time.now - 59.seconds).autologin?.should == true
end
it 'is false for users with enable_account_token' do
user_creation = FactoryGirl.build(:autologin_user_creation)
user = user_creation.instance_variable_get(:@cartodb_user)
user.enable_account_token = 'whatever'
user_creation.autologin?.should == false
end
it 'is false for disabled users' do
user_creation = FactoryGirl.build(:autologin_user_creation)
user = user_creation.instance_variable_get(:@cartodb_user)
user.enabled = false
user_creation.autologin?.should == false
end
it 'is false for users that have seen their dashboard' do
user_creation = FactoryGirl.build(:autologin_user_creation)
user = user_creation.instance_variable_get(:@cartodb_user)
user.dashboard_viewed_at = Time.now
user_creation.autologin?.should == false
end
end
describe 'validation token' do
include_context 'organization with users helper'
before(:each) do
# Disable central for these tests
Cartodb::Central.stubs(:sync_data_with_cartodb_central?).returns(false)
end
after(:all) do
Cartodb::Central.unstub(:sync_data_with_cartodb_central?)
end
it 'assigns an enable_account_token if user has not signed up with Google' do
::User.any_instance.stubs(:create_in_central).returns(true)
CartoDB::UserModule::DBService.any_instance.stubs(:enable_remote_db_user).returns(true)
user_data = FactoryGirl.build(:valid_user)
user_data.organization = @organization
user_data.google_sign_in = false
user_creation = Carto::UserCreation.new_user_signup(user_data)
user_creation.next_creation_step until user_creation.finished?
saved_user = Carto::User.order("created_at desc").limit(1).first
saved_user.enable_account_token.should_not be_nil
end
it 'does not assign an enable_account_token if user has signed up with Google' do
::User.any_instance.stubs(:create_in_central).returns(true)
CartoDB::UserModule::DBService.any_instance.stubs(:enable_remote_db_user).returns(true)
user_data = FactoryGirl.build(:valid_user)
user_data.organization = @organization
user_data.google_sign_in = true
user_creation = Carto::UserCreation.new_user_signup(user_data)
user_creation.next_creation_step until user_creation.finished?
saved_user = Carto::User.order("created_at desc").limit(1).first
saved_user.username.should == user_data.username
saved_user.enable_account_token.should be_nil
end
it 'does not assign an enable_account_token if user has signed up with GitHub' do
::User.any_instance.stubs(:create_in_central).returns(true)
CartoDB::UserModule::DBService.any_instance.stubs(:enable_remote_db_user).returns(true)
user_data = FactoryGirl.build(:valid_user)
user_data.organization = @organization
user_data.github_user_id = 123
user_creation = Carto::UserCreation.new_user_signup(user_data)
user_creation.next_creation_step until user_creation.finished?
saved_user = Carto::User.order("created_at desc").limit(1).first
saved_user.username.should == user_data.username
saved_user.enable_account_token.should be_nil
end
it 'does not assign an enable_account_token nor sends email if user had an invitation and the right token is set' do
::Resque.expects(:enqueue).with(::Resque::UserJobs::Mail::NewOrganizationUser).never
::Resque.expects(:enqueue).with(Resque::OrganizationJobs::Mail::Invitation, instance_of(String)).once
::User.any_instance.stubs(:create_in_central).returns(true)
CartoDB::UserModule::DBService.any_instance.stubs(:enable_remote_db_user).returns(true)
user_data = FactoryGirl.build(:valid_user)
user_data.organization = @organization
user_data.google_sign_in = false
invitation = Carto::Invitation.create_new(@carto_org_user_owner, [user_data.email], 'Welcome!', false)
invitation.save
user_creation = Carto::UserCreation.
new_user_signup(user_data).
with_invitation_token(invitation.token(user_data.email))
user_creation.next_creation_step until user_creation.finished?
user_creation.reload
saved_user = user_creation.user
saved_user.username.should == user_data.username
saved_user.enable_account_token.should be_nil
end
it 'does create an account if user had and invitation' do
::User.any_instance.stubs(:create_in_central).returns(true)
CartoDB::UserModule::DBService
.any_instance.stubs(:enable_remote_db_user)
.returns(true)
user_data = FactoryGirl.build(
:valid_user,
organization: @organization,
google_sign_in: false
)
invitation = Carto::Invitation.create_new(@carto_org_user_owner,
[user_data.email],
'Welcome!',
false)
invitation.save
user_creation = Carto::UserCreation.new_user_signup(user_data)
user_creation.with_invitation_token(invitation.token(user_data.email))
user_creation.save
user_creation = Carto::UserCreation.find(user_creation.id)
user_creation.next_creation_step! until user_creation.finished?
user_creation.reload
user_creation.state.should eq('success')
end
it 'does create an account if user had multiple invitations' do
::User.any_instance.stubs(:create_in_central).returns(true)
CartoDB::UserModule::DBService
.any_instance.stubs(:enable_remote_db_user)
.returns(true)
user_data = FactoryGirl.build(
:valid_user,
organization: @organization,
google_sign_in: false
)
# Dismissed invitations
4.times do
Carto::Invitation.create_new(
@carto_org_user_owner, [user_data.email], 'Welcome!', false
).save
end
invitation = Carto::Invitation.create_new(@carto_org_user_owner,
[user_data.email], 'Welcome!',
false)
invitation.save
user_creation = Carto::UserCreation.new_user_signup(user_data)
user_creation.with_invitation_token(invitation.token(user_data.email))
user_creation.save
user_creation = Carto::UserCreation.find(user_creation.id)
user_creation.next_creation_step! until user_creation.finished?
user_creation.reload
user_creation.state.should eq('success')
end
it 'with viewer invitations creates viewer users' do
::User.any_instance.stubs(:create_in_central).returns(true)
CartoDB::UserModule::DBService.any_instance.stubs(:enable_remote_db_user).returns(true)
user_data = FactoryGirl.build(:valid_user, organization: @organization, google_sign_in: false)
invitation = Carto::Invitation.create_new(@carto_org_user_owner, [user_data.email], 'Welcome!', true)
invitation.save
user_creation = Carto::UserCreation.
new_user_signup(user_data).
with_invitation_token(invitation.token(user_data.email))
user_creation.next_creation_step until user_creation.finished?
user_creation.reload
user_creation.user.viewer.should eq true
end
it 'neither creates a new User nor sends the mail and marks creation as failure if saving fails' do
Cartodb::Central.stubs(:sync_data_with_cartodb_central?).returns(false)
::User.any_instance.stubs(:save).raises('saving error')
::Resque.expects(:enqueue).with(::Resque::UserJobs::Mail::NewOrganizationUser).never
user_data = FactoryGirl.build(:valid_user)
user_data.organization = @organization
user_data.google_sign_in = true
user_creation = Carto::UserCreation.new_user_signup(user_data)
user_creation.next_creation_step until user_creation.finished?
saved_user = Carto::User.where(username: user_data.username).first
saved_user.should == nil
user_creation.reload
user_creation.state.should == 'failure'
end
after(:each) do
Cartodb::Central.stubs(:sync_data_with_cartodb_central?).returns(false)
end
it 'neither creates a new User nor sends the mail and marks creation as failure if Central fails' do
Cartodb::Central.stubs(:sync_data_with_cartodb_central?).returns(true)
::User.any_instance.stubs(:create_in_central).raises('Error on state creating_user_in_central, mark_as_failure: false. Error: Application server responded with http 422: {"errors":["Existing username."]}')
::Resque.expects(:enqueue).with(::Resque::UserJobs::Mail::NewOrganizationUser).never
user_data = FactoryGirl.build(:valid_user)
user_data.organization = @organization
user_data.google_sign_in = true
user_creation = Carto::UserCreation.new_user_signup(user_data)
user_creation.next_creation_step until user_creation.finished?
saved_user = Carto::User.where(username: user_data.username).first
saved_user.should == nil
user_creation.reload
user_creation.state.should == 'failure'
end
it 'neither creates a new User nor sends the mail and marks creation as failure if Central has a registered user matching username' do
user = prepare_fake_central_user
# This tests only matching usernames
user.email = 'other@whatever.com'
::Resque.expects(:enqueue).with(::Resque::UserJobs::Mail::NewOrganizationUser).never
user.organization = @organization
user_creation = Carto::UserCreation.new_user_signup(user)
user_creation.next_creation_step until user_creation.finished?
Carto::User.where(username: user.username).first.should == nil
user_creation.reload
user_creation.state.should == 'failure'
end
it 'neither creates a new User nor sends the mail and marks creation as failure if Central has a registered user matching email' do
user = prepare_fake_central_user
# This tests only matching emails
user.username = 'other_whatever'
::Resque.expects(:enqueue).with(::Resque::UserJobs::Mail::NewOrganizationUser).never
user.organization = @organization
user_creation = Carto::UserCreation.new_user_signup(user)
user_creation.next_creation_step until user_creation.finished?
Carto::User.where(username: user.username).first.should == nil
user_creation.reload
user_creation.state.should == 'failure'
end
it 'neither creates a new User nor sends the mail and marks creation as failure if username es empty' do
user = prepare_fake_central_user
# This tests only matching emails
user.username = nil
::Resque.expects(:enqueue).with(::Resque::UserJobs::Mail::NewOrganizationUser).never
user.organization = @organization
expect {
user_creation = Carto::UserCreation.new_user_signup(user)
}.to raise_error
end
def prepare_fake_central_user
Cartodb::Central.stubs(:sync_data_with_cartodb_central?).returns(true)
fake_central_client = {}
fake_central_client.stubs(:create_organization_user).returns(true)
::User.any_instance.stubs(:cartodb_central_client).returns(fake_central_client)
Cartodb::Central.stubs(:new).returns(fake_central_client)
user = FactoryGirl.build(:valid_user)
central_user_data = JSON.parse(user.to_json)
# Central doesn't return exactly the same attributes, but this is good enough for testing
Cartodb::Central.any_instance.stubs(:get_user).returns(central_user_data)
fake_central_client.stubs(:get_user).returns(central_user_data)
user
end
end
describe 'validation email' do
include_context 'organization with users helper'
# INFO : this mail contains validation link
it 'triggers a ::Resque::UserJobs::Mail::NewOrganizationUser' do
::User.any_instance.stubs(:create_in_central).returns(true)
CartoDB::UserModule::DBService.any_instance.stubs(:enable_remote_db_user).returns(true)
::Resque.expects(:enqueue).with(Resque::UserJobs::Mail::NewOrganizationUser, instance_of(String)).once
user_data = FactoryGirl.build(:valid_user)
user_data.organization = @organization
user_data.google_sign_in = false
user_creation = Carto::UserCreation.new_user_signup(user_data)
user_creation.next_creation_step until user_creation.finished?
end
it 'should trigger load_common_data in the user if common_data_url is setted' do
::User.any_instance.stubs(:create_in_central).returns(true)
CartoDB::UserModule::DBService.any_instance.stubs(:enable_remote_db_user).returns(true)
::User.any_instance.expects(:load_common_data).with('http://www.example.com').once
user_data = FactoryGirl.build(:valid_user)
user_data.organization = @organization
user_data.google_sign_in = false
user_creation = Carto::UserCreation.new_user_signup(user_data)
user_creation.set_common_data_url("http://www.example.com")
user_creation.next_creation_step until user_creation.finished?
end
it 'should not trigger load_common_data in the user if common_data_url is not setted' do
::User.any_instance.stubs(:create_in_central).returns(true)
CartoDB::UserModule::DBService.any_instance.stubs(:enable_remote_db_user).returns(true)
::User.any_instance.expects(:load_common_data).with('http://www.example.com').never
user_data = FactoryGirl.build(:valid_user)
user_data.organization = @organization
user_data.google_sign_in = false
user_creation = Carto::UserCreation.new_user_signup(user_data)
user_creation.next_creation_step until user_creation.finished?
end
it 'should send invitation email but not validation email if user is created via API' do
::User.any_instance.stubs(:create_in_central).returns(true)
CartoDB::UserModule::DBService.any_instance.stubs(:enable_remote_db_user).returns(true)
::Resque.expects(:enqueue).with(Resque::OrganizationJobs::Mail::Invitation, instance_of(String)).never
::Resque.expects(:enqueue).with(Resque::UserJobs::Mail::NewOrganizationUser, instance_of(String)).once
user_data = FactoryGirl.build(:valid_user)
user_data.organization = @organization
user_creation = Carto::UserCreation.new_user_signup(user_data, Carto::UserCreation::CREATED_VIA_API)
user_creation.next_creation_step until user_creation.finished?
end
end
describe 'organization overquota email' do
include_context 'organization with users helper'
it 'triggers a DiskQuotaLimitReached mail if organization has run out of quota for new users' do
::User.any_instance.stubs(:create_in_central).returns(true)
CartoDB::UserModule::DBService.any_instance.stubs(:enable_remote_db_user).returns(true)
::Resque.expects(:enqueue).with(Resque::UserJobs::Mail::NewOrganizationUser, instance_of(String)).once
::Resque.expects(:enqueue).with(Resque::OrganizationJobs::Mail::DiskQuotaLimitReached, instance_of(String)).once
user_data = FactoryGirl.build(:valid_user)
user_data.organization = @organization
@organization.quota_in_bytes = @organization.assigned_quota + @organization.default_quota_in_bytes + 1
@organization.save
user_creation = Carto::UserCreation.new_user_signup(user_data)
user_creation.next_creation_step until user_creation.finished?
end
end
describe 'organization over seats email' do
include_context 'organization with users helper'
it 'triggers a SeatLimitReached mail if organization has run out of seats new users' do
::User.any_instance.stubs(:create_in_central).returns(true)
CartoDB::UserModule::DBService.any_instance.stubs(:enable_remote_db_user).returns(true)
::Resque.expects(:enqueue).with(Resque::UserJobs::Mail::NewOrganizationUser, instance_of(String)).once
::Resque.expects(:enqueue).with(Resque::OrganizationJobs::Mail::SeatLimitReached, instance_of(String)).once
user_data = FactoryGirl.build(:valid_user)
user_data.organization = @organization
@organization.seats = 4
@organization.save
user_creation = Carto::UserCreation.new_user_signup(user_data)
user_creation.next_creation_step until user_creation.finished?
end
it 'doesnt trigger any unexpected mails if organization is ok' do
::User.any_instance.stubs(:create_in_central).returns(true)
CartoDB::UserModule::DBService.any_instance.stubs(:enable_remote_db_user).returns(true)
::Resque.expects(:enqueue).with(Resque::UserJobs::Mail::NewOrganizationUser, instance_of(String)).once
::Resque.expects(:enqueue).with(Resque::OrganizationJobs::Mail::SeatLimitReached, instance_of(String)).never
::Resque.expects(:enqueue).with(Resque::OrganizationJobs::Mail::DiskQuotaLimitReached, instance_of(String)).never
user_data = FactoryGirl.build(:valid_user)
user_data.organization = @organization
@organization.seats = 15
@organization.save
user_creation = Carto::UserCreation.new_user_signup(user_data)
user_creation.next_creation_step until user_creation.finished?
end
end
describe '#initialize_user' do
it 'initializes users with http_authentication without organization' do
created_via = Carto::UserCreation::CREATED_VIA_HTTP_AUTENTICATION
user = FactoryGirl.build(:valid_user)
user.organization_id.should == nil
user_creation = Carto::UserCreation.new_user_signup(user, created_via)
initialized_user = user_creation.send(:initialize_user)
initialized_user.should_not be_nil
initialized_user.organization_id.should be_nil
end
end
describe 'state machine' do
before(:each) do
CartoDB::UserModule::DBService.any_instance.stubs(:enable_remote_db_user).returns(true)
created_via = Carto::UserCreation::CREATED_VIA_HTTP_AUTENTICATION
user = FactoryGirl.build(:valid_user)
@user_creation = Carto::UserCreation.new_user_signup(user, created_via)
end
after(:each) do
@user_creation.user.destroy
end
def creation_steps(user_creation)
states = [user_creation.state]
until user_creation.finished?
user_creation.next_creation_step
states << user_creation.state
end
states
end
it 'with Central and builder, does all the steps' do
Cartodb::Central.stubs(:sync_data_with_cartodb_central?).returns(true)
User.any_instance.stubs(:validate_credentials_not_taken_in_central).returns(true)
@user_creation.expects(:create_in_central).once
@user_creation.expects(:load_common_data).once
creation_steps(@user_creation).should eq ["enqueuing", "creating_user", "validating_user", "saving_user",
"promoting_user", "creating_user_in_central", "load_common_data",
"success"]
end
it 'without Central, skips creation in central' do
Cartodb::Central.stubs(:sync_data_with_cartodb_central?).returns(false)
@user_creation.expects(:create_in_central).never
@user_creation.expects(:load_common_data).once
creation_steps(@user_creation).should eq ["enqueuing", "creating_user", "validating_user", "saving_user",
"promoting_user", "load_common_data", "success"]
end
it 'with Central as a viewer, skips loading common data' do
Cartodb::Central.stubs(:sync_data_with_cartodb_central?).returns(true)
User.any_instance.stubs(:validate_credentials_not_taken_in_central).returns(true)
@user_creation.viewer = true
@user_creation.expects(:create_in_central).once
@user_creation.expects(:load_common_data).never
creation_steps(@user_creation).should eq ["enqueuing", "creating_user", "validating_user", "saving_user",
"promoting_user", "creating_user_in_central", "success"]
end
it 'without Central as a viewer, skips loading common data and creation in central' do
Cartodb::Central.stubs(:sync_data_with_cartodb_central?).returns(false)
@user_creation.viewer = true
@user_creation.expects(:create_in_central).never
@user_creation.expects(:load_common_data).never
creation_steps(@user_creation).should eq ["enqueuing", "creating_user", "validating_user", "saving_user",
"promoting_user", "success"]
end
end
end