path '/api/users' do
let(:registration_params) do
{
user: {
email: email,
password: password,
password_confirmation: password_confirmation,
profile_attributes: {
first_name: first_name,
currency: currency
}
}
}
end
let(:email) { 'some@email.com' }
let(:password) { 'password' }
let(:password_confirmation) { 'password' }
let(:first_name) { 'Roberto' }
let(:currency) { 'EUR' }
let(:country_code) { 'GE' }
let(:country_region_code) { 'TB' }
let(:last_user) { User.last }
before do
create_settings :first_name
allow(StoreTagsFromCookies).to receive(:call)
end
post 'Publishes the sign_up form' do
tags 'Users'
parameter name: :registration_params, in: :body, schema: {
type: :object,
properties: {
user: {
type: :object,
properties: {
email: { type: :string },
password: { type: :string },
password_confirmation: { type: :string },
profile_attributes: {
type: :object,
properties: {
first_name: { type: :string },
currency: { type: :string }
}
}
}
}
}
}
before do
allow(RequestStore).to receive(:store) do
{
request_ip: '128.128.128.128',
request_geoip_country_code: country_code,
request_geoip_region_code: country_region_code
}
end
end
response '201', 'After successful sign up confirmation email will be send to user.' \
' This mail contains link with confirmation url like'\
' http://casino.softswiss.com/users/confirmation?confirmation_token=3p8iHqcHAsY3jgjxUoJr .' \
' When the user clicks this link he come to casino site and frontend js is responsible for handling' \
' this request and seconding confirmation request to the backend server (See "Confirm User").' do
consumes 'application/json'
produces 'application/vnd.softswiss.v1+json'
before do
User.all.destroy_all
end
run_test! do
expect(User.count).not_to be_zero
expect(License.count).not_to be_zero
expect(last_user.last_tracked_country).to eq(country_code)
expect(last_user.last_tracked_country_region).to eq(country_region_code)
expect(last_user.email).to eq(email)
expect(last_user.profile.first_name).to eq(first_name)
expect(json_response).to respond_with_status(:created)
end
end
end
context 'when bonus code provided by user' do
let(:bonus_code) { ' code ' }
post 'Publishes the sign_up form' do
description 'User registered with bonus code'
tags 'Users'
parameter name: :registration_params, in: :body, schema: {
type: :object,
properties: {
user: {
type: :object,
properties: {
email: { type: :string },
password: { type: :string },
password_confirmation: { type: :string },
profile_attributes: {
type: :object,
properties: {
first_name: { type: :string },
currency: { type: :string }
}
}
}
}
}
}
response '201', 'When user provides bonus code during registration, bonus would be available.',
document: false do
consumes 'application/json'
produces 'application/vnd.softswiss.v1+json'
before do
registration_params[:user].merge!(bonus_code: bonus_code)
BonusIssue.all.destroy_all
end
run_test! { expect(BonusIssue.count).to be_zero }
end
end
end
post 'Publishes the sign_up form' do
description 'Set writable group'
tags 'Users'
parameter name: :registration_params, in: :body, schema: {
type: :object,
properties: {
user: {
type: :object,
properties: {
email: { type: :string },
password: { type: :string },
password_confirmation: { type: :string },
profile_attributes: {
type: :object,
properties: {
first_name: { type: :string },
currency: { type: :string }
}
}
}
}
}
}
response '201', 'See more about writable groups in Player\s groups section' do
consumes 'application/json'
produces 'application/vnd.softswiss.v1+json'
let(:group) do
create(:group, frontend_identifier: 'welcome:opt1', public: true, user_writable: true, dynamic: false)
end
before do
registration_params[:user].merge!(groups: [group.frontend_identifier])
User.all.destroy_all
end
run_test! do
expect(User.count).not_to be_zero
expect(last_user.groups).to contain_exactly(group)
expect(License.count).not_to be_zero
expect(json_response).to respond_with_status(:created)
end
end
end
describe 'when butler restriction exists', doc: false do
before do
User.all.destroy_all
allow(Butler).to receive(:actions).and_return('*' => butler_proc)
allow(Butler::RejectHandler)
.to receive(:call).with(instance_of(ActiveSupport::HashWithIndifferentAccess), instance_of(String))
end
post 'Publishes the sign_up form' do
shared_examples 'Responds with restriction' do
response '403', 'Responds with restriction' do
consumes 'application/json'
produces 'application/vnd.softswiss.v1+json'
run_test! do
expect(User.count).to be_zero
expect(License.count).to be_zero
expect(json_response).to eq('reason' => 'ksa_registration_restricted')
expect(Butler::RejectHandler)
.to have_received(:call).with(hash_including(registration_params), 'ksa_registration_restricted').once
end
end
end
parameter name: :registration_params, in: :body, schema: {
type: :object,
properties: {
user: {
type: :object,
properties: {
email: { type: :string },
password: { type: :string },
password_confirmation: { type: :string },
profile_attributes: {
type: :object,
properties: {
first_name: { type: :string },
currency: { type: :string }
}
}
}
}
}
}
context 'when parameter restriction' do
let(:butler_proc) do
proc {
parameter :user, :email do
value 'some@email.com'
reason 'ksa_registration_restricted'
end
}
end
it_behaves_like 'Responds with restriction'
end
context 'when ip restriction' do
let(:butler_proc) do
proc {
ip('127.0.0.0/24') do
reason 'ksa_registration_restricted'
end
}
end
it_behaves_like 'Responds with restriction'
end
end
end
context 'when maltian license enabled' do
around do |ex|
prev_licenses = Thread.current[:enabled_licences]
Thread.current[:enabled_licences] = nil
with_settings('licenses' => %w[MT]) { ex.run }
Thread.current[:enabled_licences] = prev_licenses
end
post 'Publishes the sign_up form' do
description 'Set reality check limit'
tags 'Users'
parameter name: :registration_params, in: :body, schema: {
type: :object,
properties: {
user: {
type: :object,
properties: {
email: { type: :string },
password: { type: :string },
password_confirmation: { type: :string },
profile_attributes: {
type: :object,
properties: {
first_name: { type: :string },
currency: { type: :string }
}
}
}
}
}
}
response '201', '', document: false do
consumes 'application/json'
produces 'application/vnd.softswiss.v1+json'
before do
UserLimits::Base.all.destroy_all
end
run_test! do
expect(UserLimits::Base.count).not_to be_zero
expect(json_response).to respond_with_status(:created)
end
end
end
end
context 'when maltian license disabled' do
before { allow(UserLimits::RealityCheck).to receive(:enabled?).and_return(false) }
post 'Publishes the sign_up form' do
description 'Doesn\'t creates reality check limit'
tags 'Users'
parameter name: :registration_params, in: :body, schema: {
type: :object,
properties: {
user: {
type: :object,
properties: {
email: { type: :string },
password: { type: :string },
password_confirmation: { type: :string },
profile_attributes: {
type: :object,
properties: {
first_name: { type: :string },
currency: { type: :string }
}
}
}
}
}
}
response '201', '', document: false do
consumes 'application/json'
produces 'application/vnd.softswiss.v1+json'
before do
UserLimits::Base.all.destroy_all
end
run_test! do
expect(UserLimits::Base.count).to be_zero
expect(json_response).to respond_with_status(:created)
end
end
end
end
context 'when registration is restricted by latvian license rules' do
post 'Publishes the sign_up form' do
description 'Not writable groups are not allowed'
tags 'Users'
parameter name: :registration_params, in: :body, schema: {
type: :object,
properties: {
user: {
type: :object,
properties: {
email: { type: :string },
password: { type: :string },
password_confirmation: { type: :string },
profile_attributes: {
type: :object,
properties: {
first_name: { type: :string },
currency: { type: :string },
personal_id_number: { type: :string }
}
}
}
}
}
}
response '422', '', document: false do
consumes 'application/json'
produces 'application/vnd.softswiss.v1+json'
around do |ex|
prev_licenses = Thread.current[:enabled_licences]
Thread.current[:enabled_licences] = nil
with_settings('licenses' => %w[LV]) { ex.run }
Thread.current[:enabled_licences] = prev_licenses
end
before do
User.all.destroy_all
registration_params[:user][:profile_attributes].merge!(personal_id_number: 'wrong')
allow(LicenseRules::Latvian).to receive(:process_failed_registration).once
end
run_test! do
expect(User.all.count).to be_zero
expect(LicenseRules::Latvian).to have_received(:process_failed_registration).once
expect(json_response).to respond_with_error(profile: { personal_id_number: :latvian_license_restriction })
expect(json_response).to respond_with_status(:unprocessable_entity)
end
end
end
end
context 'when latvian license and user is already registered' do
post 'Invalid attributes' do
tags 'Registration'
parameter name: :registration_params, in: :body, schema: {
type: :object,
properties: {
user: {
type: :object,
properties: {
email: { type: :string },
password: { type: :string },
password_confirmation: { type: :string },
profile_attributes: {
type: :object,
properties: {
first_name: { type: :string },
currency: { type: :string }
}
}
}
}
}
}
response '422', '', document: false do
consumes 'application/json'
produces 'application/vnd.softswiss.v1+json'
around do |ex|
prev_licenses = Thread.current[:enabled_licences]
Thread.current[:enabled_licences] = nil
with_settings('licenses' => %w[LV]) { ex.run }
Thread.current[:enabled_licences] = prev_licenses
end
before do
allow(LicenseRules::Checker).to receive(:can_registration?).and_return(true)
allow(LicenseRules::Latvian).to receive(:process_failed_registration).and_call_original
User.all.destroy_all
create(:user, email: email)
end
run_test! do
expect(LicenseRules::Latvian).to have_received(:process_failed_registration)
expect(json_response).to respond_with_status(:unprocessable_entity)
end
end
end
end
post 'Not writable groups are not allowed' do
tags 'Registration'
parameter name: :registration_params, in: :body, schema: {
type: :object,
properties: {
user: {
type: :object,
properties: {
email: { type: :string },
password: { type: :string },
password_confirmation: { type: :string },
profile_attributes: {
type: :object,
properties: {
first_name: { type: :string },
currency: { type: :string }
}
}
}
}
}
}
response '201', '', document: false do
consumes 'application/json'
produces 'application/vnd.softswiss.v1+json'
let(:group) do
create(:group, frontend_identifier: 'welcome:opt1', public: true, user_writable: false, dynamic: false)
end
before do
registration_params[:user].merge!(groups: [group.frontend_identifier])
User.all.destroy_all
end
run_test! do
expect(User.count).not_to be_zero
expect(last_user.groups).to be_empty
expect(json_response).to respond_with_status(:created)
end
end
end
describe 'profile error' do
let(:email) { 'email.com' }
let(:password_confirmation) { 'wrong' }
let(:first_name) { nil }
post 'Publishes the sign_up form' do
description 'Invalid attributes'
tags 'Users'
parameter name: :registration_params, in: :body, schema: {
type: :object,
properties: {
user: {
type: :object,
properties: {
email: { type: :string },
password: { type: :string },
password_confirmation: { type: :string },
profile_attributes: {
type: :object,
properties: {
first_name: { type: :string },
currency: { type: :string }
}
}
}
}
}
}
response '422', '', document: false do
consumes 'application/json'
produces 'application/vnd.softswiss.v1+json'
before do
User.all.destroy_all
end
run_test! do
expect(User.all.count).to be_zero
expect(json_response).to respond_with_error(email: :invalid)
expect(json_response).to respond_with_error(password_confirmation: :confirmation)
expect(json_response).to respond_with_error(profile: { first_name: :blank })
expect(json_response).to respond_with_status(:unprocessable_entity)
end
end
end
end
context 'when Captcha enabled on registration' do
let(:captcha) { 'captcha-here' }
let(:verify_options) do
{
response: captcha,
secret_key: 'SECRET_V2'
}
end
before do
registration_params[:user].merge!(captcha: captcha)
create_settings(:captcha)
allow_any_instance_of(Recaptcha::Adapters::ControllerMethods)
.to receive(:verify_recaptcha)
.with(verify_options)
.and_return(verify_result)
User.all.destroy_all
end
around do |ex|
with_settings(
'recaptcha' => { secret_key: 'SECRET_V2' },
'recaptcha_v3' => { secret_key: 'SECRET_V3', minimum_score: 0.4 }
) do
ex.run
end
end
context 'when User submitted correct captcha' do
let(:verify_result) { true }
post 'Publishes the sign_up form' do
description 'Creates user'
tags 'Users'
parameter name: :registration_params, in: :body, schema: {
type: :object,
properties: {
user: {
type: :object,
properties: {
email: { type: :string },
password: { type: :string },
password_confirmation: { type: :string },
profile_attributes: {
type: :object,
properties: {
first_name: { type: :string },
currency: { type: :string }
}
}
}
}
}
}
response '201', '', document: false do
consumes 'application/json'
produces 'application/vnd.softswiss.v1+json'
run_test! do
expect(User.count).not_to be_zero
expect(json_response).to respond_with_status(:created)
end
end
end
context 'when mobile phone is submitted' do
before do
registration_params.dig(:user, :profile_attributes).merge!(mobile_phone: mobile_phone)
VerifiedPhone.all.destroy_all
end
context 'when phone number is valid' do
let(:mobile_phone) { Faker::Base.numerify('+37529#######') }
post 'Publishes the sign_up form' do
description 'creates verified phone'
tags 'Users'
parameter name: :registration_params, in: :body, schema: {
type: :object,
properties: {
user: {
type: :object,
properties: {
email: { type: :string },
password: { type: :string },
password_confirmation: { type: :string },
profile_attributes: {
type: :object,
properties: {
first_name: { type: :string },
currency: { type: :string }
}
}
}
}
}
}
response '201', '', document: false do
consumes 'application/json'
produces 'application/vnd.softswiss.v1+json'
run_test! do
expect(User.count).not_to be_zero
expect(VerifiedPhone.count).not_to be_zero
expect(json_response).to respond_with_status(:created)
end
end
end
end
context 'when phone number is invalid' do
let(:mobile_phone) { '123' }
post 'Publishes the sign_up form' do
description 'does not create verified phone'
tags 'Users'
parameter name: :registration_params, in: :body, schema: {
type: :object,
properties: {
user: {
type: :object,
properties: {
email: { type: :string },
password: { type: :string },
password_confirmation: { type: :string },
profile_attributes: {
type: :object,
properties: {
first_name: { type: :string },
currency: { type: :string }
}
}
}
}
}
}
response '422', '', document: false do
consumes 'application/json'
produces 'application/vnd.softswiss.v1+json'
run_test! do
expect(User.count).to be_zero
expect(VerifiedPhone.count).to be_zero
expect(json_response).to respond_with_status(:unprocessable_entity)
end
end
end
end
end
context 'when captcha v3 is enabled' do
let(:verify_options) do
{
response: captcha,
secret_key: 'SECRET_V3',
minimum_score: 0.4,
action: nil
}
end
before do
enable_recaptcha_v3
end
post 'Publishes the sign_up form' do
description 'creates user'
tags 'Users'
parameter name: :registration_params, in: :body, schema: {
type: :object,
properties: {
user: {
type: :object,
properties: {
email: { type: :string },
password: { type: :string },
password_confirmation: { type: :string },
profile_attributes: {
type: :object,
properties: {
first_name: { type: :string },
currency: { type: :string }
}
}
}
}
}
}
response '201', '', document: false do
consumes 'application/json'
produces 'application/vnd.softswiss.v1+json'
run_test! do
expect(User.count).not_to be_zero
expect(json_response).to respond_with_status(:created)
end
end
end
end
end
context 'when User submitted invalid captcha' do
let(:verify_result) { false }
post 'Publishes the sign_up form' do
description 'Doesn\'t create user'
tags 'Users'
parameter name: :registration_params, in: :body, schema: {
type: :object,
properties: {
user: {
type: :object,
properties: {
email: { type: :string },
password: { type: :string },
password_confirmation: { type: :string },
profile_attributes: {
type: :object,
properties: {
first_name: { type: :string },
currency: { type: :string }
}
}
}
}
}
}
response '422', '', document: false do
consumes 'application/json'
produces 'application/vnd.softswiss.v1+json'
run_test! do
expect(User.count).to be_zero
expect(json_response).to respond_with_status(:unprocessable_entity)
expect(json_response).to respond_with_error(captcha: :invalid)
end
end
end
context 'when email is already in use' do
before { create(:user, email: email) }
post 'Publishes the sign_up form' do
description 'Doesn\'t create user'
tags 'Users'
parameter name: :registration_params, in: :body, schema: {
type: :object,
properties: {
user: {
type: :object,
properties: {
email: { type: :string },
password: { type: :string },
password_confirmation: { type: :string },
profile_attributes: {
type: :object,
properties: {
first_name: { type: :string },
currency: { type: :string }
}
}
}
}
}
}
response '422', '', document: false do
consumes 'application/json'
produces 'application/vnd.softswiss.v1+json'
run_test! do
expect(json_response).to respond_with_status(:unprocessable_entity)
expect(json_response).to respond_with_error(captcha: :invalid)
expect(json_response).not_to respond_with_error(email: :taken)
end
end
end
end
context 'when captcha v3 is enabled' do
let(:verify_options) do
{
response: captcha,
secret_key: 'SECRET_V3',
minimum_score: 0.4,
action: nil
}
end
before do
enable_recaptcha_v3
end
post 'Publishes the sign_up form' do
description 'creates user'
tags 'Users'
parameter name: :registration_params, in: :body, schema: {
type: :object,
properties: {
user: {
type: :object,
properties: {
email: { type: :string },
password: { type: :string },
password_confirmation: { type: :string },
profile_attributes: {
type: :object,
properties: {
first_name: { type: :string },
currency: { type: :string }
}
}
}
}
}
}
response '422', '', document: false do
consumes 'application/json'
produces 'application/vnd.softswiss.v1+json'
run_test! do
expect(User.count).to be_zero
expect(json_response).to respond_with_status(:unprocessable_entity)
expect(json_response).to respond_with_error(captcha: :invalid)
end
end
end
end
end
end
describe 'Profile error', doc: false do
let(:password) { email }
let(:password_confirmation) { email }
post 'Publishes the sign_up form' do
description 'Invalid attributes'
tags 'Users'
parameter name: :registration_params, in: :body, schema: {
type: :object,
properties: {
user: {
type: :object,
properties: {
email: { type: :string },
password: { type: :string },
password_confirmation: { type: :string },
profile_attributes: {
type: :object,
properties: {
first_name: { type: :string },
currency: { type: :string }
}
}
}
}
}
}
response '422', 'Unprocessable entity' do
consumes 'application/json'
produces 'application/vnd.softswiss.v1+json'
before do
User.all.destroy_all
end
run_test! do
expect(User.count).to be_zero
expect(json_response).to respond_with_error(password: :email_equivalent)
expect(json_response).to respond_with_status(:unprocessable_entity)
end
end
end
end
end