Initial commit
This commit is contained in:
409
spec/models/user_spec.rb
Normal file
409
spec/models/user_spec.rb
Normal file
@@ -0,0 +1,409 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe User, type: :model do
|
||||
before { allow(Barong::App.config).to receive_messages(kyc_provider: 'local') }
|
||||
|
||||
let!(:create_member_permission) do
|
||||
create :permission,
|
||||
role: 'member'
|
||||
end
|
||||
context 'User model basic syntax' do
|
||||
## Test of data length
|
||||
it { should validate_length_of(:data) }
|
||||
|
||||
# 1100 char string
|
||||
let(:big_str) { "string bar"*11 }
|
||||
|
||||
it { should_not allow_value(big_str).for(:data)}
|
||||
|
||||
## Test of validations
|
||||
it { should validate_presence_of(:email) }
|
||||
it { should have_many(:documents).dependent(:destroy) }
|
||||
|
||||
## Test of relationships
|
||||
it { should have_many(:profiles).dependent(:destroy) }
|
||||
|
||||
## Test of UID creation
|
||||
it 'creates default uid with prefix ID' do
|
||||
default_user = create(:user)
|
||||
expect(default_user.uid).to start_with(Barong::App.config.uid_prefix)
|
||||
end
|
||||
|
||||
it 'uid prefix can be changed by ENV' do
|
||||
allow(Barong::App.config).to receive(:uid_prefix).and_return('GG')
|
||||
|
||||
default_user = create(:user)
|
||||
expect(default_user.uid).to start_with('GG')
|
||||
end
|
||||
|
||||
it 'uid_prefix doesnt case sensitive and always converts to big letters' do
|
||||
allow(Barong::App.config).to receive(:uid_prefix).and_return('aa')
|
||||
|
||||
default_user = create(:user)
|
||||
expect(default_user.uid).to start_with('AA')
|
||||
end
|
||||
|
||||
it do
|
||||
usr = create(:user)
|
||||
payload = usr.as_payload
|
||||
expect(payload['email']).to eq(usr.email)
|
||||
end
|
||||
|
||||
describe '#referral' do
|
||||
let!(:user1) { create(:user) }
|
||||
let!(:user2) { create(:user, referral_id: user1.id) }
|
||||
|
||||
it 'return error when referral doesnt exist' do
|
||||
record = User.new(uid: 'ID122312323', email: 'test@barong.io', password: 'Oo213Wqw')
|
||||
record.referral_id = 0
|
||||
record.valid?
|
||||
|
||||
expect(record.errors[:referral_id]).to eq(['doesnt_exist'])
|
||||
end
|
||||
|
||||
it 'return refferal uid' do
|
||||
expect(user2.referral_uid).to eq user1.uid
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#submitted_profile' do
|
||||
let!(:user_with_drafted_profile) { create(:user) }
|
||||
let!(:user_with_submitted_profiles) { create(:user) }
|
||||
let!(:user_without_profile) { create(:user) }
|
||||
let!(:drafted_profile) { create(:profile, user: user_with_drafted_profile) }
|
||||
let!(:submitted_profile) { create(:profile, user: user_with_submitted_profiles, state: 'submitted') }
|
||||
|
||||
it { expect(user_with_drafted_profile.submitted_profile).to eq nil }
|
||||
it { expect(user_without_profile.submitted_profile).to eq nil }
|
||||
it { expect(user_with_submitted_profiles.submitted_profile).to eq submitted_profile }
|
||||
end
|
||||
|
||||
describe '#drafted_profile' do
|
||||
let!(:user_with_drafted_profile) { create(:user) }
|
||||
let!(:user_without_profile) { create(:user) }
|
||||
let!(:drafted_profile) { create(:profile, user: user_with_drafted_profile) }
|
||||
|
||||
it { expect(user_with_drafted_profile.drafted_profile).to eq drafted_profile }
|
||||
it { expect(user_without_profile.drafted_profile).to eq nil }
|
||||
end
|
||||
|
||||
describe '#password' do
|
||||
it { should_not allow_value('Password1').for(:password)}
|
||||
it { should_not allow_value('Password1123').for(:password)}
|
||||
it { should_not allow_value('password').for(:password)}
|
||||
it { should_not allow_value('password1').for(:password)}
|
||||
it { should_not allow_value('Qq123123').for(:password)}
|
||||
it { should_not allow_value('QqQq123123').for (:password)}
|
||||
it { should_not allow_value('X2qL32').for(:password)}
|
||||
it { should_not allow_value('eoV0qu').for(:password)}
|
||||
it { should allow_value('Iequ4geiEWQw').for(:password)}
|
||||
it { should allow_value('Xwqe213PZCXwe').for(:password)}
|
||||
it { should allow_value('Kal31ewwqXrew').for(:password)}
|
||||
end
|
||||
|
||||
let(:uploaded_file) { fixture_file_upload('/files/documents_test.jpg', 'image/jpg') }
|
||||
|
||||
context 'User with 2 or more documents' do
|
||||
it do
|
||||
user = User.create!(email: 'test@gmail.com', password: 'KeeKi7zoWExzc')
|
||||
expect(User.count).to eq 1
|
||||
document1 = user.documents.create!(upload: uploaded_file,
|
||||
doc_type: 'Passport',
|
||||
doc_number: 'MyString',
|
||||
doc_expire: '01-01-3020')
|
||||
document2 = user.documents.create!(upload: uploaded_file,
|
||||
doc_type: 'Passport',
|
||||
doc_number: 'MyString',
|
||||
doc_expire: '01-02-3020')
|
||||
expect(user.reload.documents).to eq([document1, document2])
|
||||
end
|
||||
|
||||
after(:all) { User.destroy_all }
|
||||
end
|
||||
|
||||
describe 'Iso8601TimeFormat' do
|
||||
let!(:user) { create(:user) }
|
||||
around(:each) { |example| Time.use_zone('Pacific/Midway') { example.run } }
|
||||
|
||||
it 'parses time in utc and iso8601' do
|
||||
expect(user.format_iso8601_time(user.created_at)).to \
|
||||
eq user.created_at.utc.iso8601
|
||||
end
|
||||
|
||||
it 'skips nil' do
|
||||
expect(user.format_iso8601_time(nil)).to eq nil
|
||||
end
|
||||
|
||||
it 'parses date to iso8601' do
|
||||
expect(user.format_iso8601_time(user.created_at.to_date)).to \
|
||||
eq user.created_at.to_date.iso8601
|
||||
end
|
||||
end
|
||||
|
||||
describe 'States and labels dependency' do
|
||||
let(:reqs_list) { {} }
|
||||
let!(:create_permissions) do
|
||||
create :permission, role: 'member'
|
||||
end
|
||||
|
||||
before do
|
||||
allow(BarongConfig).to receive(:list) { reqs_list }
|
||||
end
|
||||
|
||||
context 'function testing' do
|
||||
let!(:user) { create(:user) }
|
||||
let!(:user_with_no_labels) { create(:user) }
|
||||
let!(:user_with_labels) do
|
||||
create(:label, user_id: user.id, key: 'email', value: 'verified', scope: 'private')
|
||||
create(:label, user_id: user.id, key: 'phone', value: 'verified', scope: 'private')
|
||||
end
|
||||
let(:reqs_list) {
|
||||
{
|
||||
"activation_requirements" => {
|
||||
"phone" => "verified",
|
||||
"documents" => "verified"
|
||||
},
|
||||
"state_triggers" => {
|
||||
"active_one_of_1_label" => ['email'],
|
||||
"active_one_of_3_labels" => ['first', 'second', 'third']
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
context 'labels_include?' do
|
||||
it { expect(user.labels_include?({ 'email' => 'verified' })).to be_truthy }
|
||||
|
||||
it { expect(user.labels_include?({ 'email' => 'pending' })).to be_falsey }
|
||||
|
||||
it { expect(user.labels_include?({ 'email' => 'verified', 'phone' => 'verified' })).to be_truthy }
|
||||
|
||||
it { expect(user.labels_include?({ 'email' => 'verified', 'phone' => 'pending' })).to be_falsey }
|
||||
end
|
||||
|
||||
context 'private_labels_to_hash' do
|
||||
it { expect(user.private_labels_to_hash).to eq({ 'email' => 'verified', 'phone' => 'verified' }) }
|
||||
|
||||
it { expect(user_with_no_labels.private_labels_to_hash).to eq({}) }
|
||||
end
|
||||
end
|
||||
|
||||
describe 'testing workability with ALL mapping type' do
|
||||
let!(:user) { create(:user, state: 'pending') }
|
||||
let(:reqs_list) {
|
||||
{
|
||||
"activation_requirements" => {
|
||||
"phone" => "verified",
|
||||
"documents" => "verified"
|
||||
},
|
||||
"state_triggers" => {
|
||||
"active_one_of_1_label" => ['email'],
|
||||
"active_one_of_3_labels" => ['first', 'second', 'third']
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
context 'changing state on adding label' do
|
||||
context 'sucessfully' do
|
||||
it 'changes state when only one label required' do
|
||||
# email required
|
||||
expect(user.state).to eq('pending')
|
||||
|
||||
user.labels.create(key: 'email', value: 'verified', scope: 'private')
|
||||
expect(user.state).to eq('active_one_of_1_label')
|
||||
end
|
||||
|
||||
it 'rollback from active to pending only in case of deleted one of activation reqs' do
|
||||
# [phone documents] required
|
||||
expect(user.state).to eq('pending')
|
||||
|
||||
user.labels.create(key: 'phone', value: 'verified', scope: 'private')
|
||||
expect(user.state).to eq('pending')
|
||||
|
||||
user.labels.create(key: 'documents', value: 'verified', scope: 'private')
|
||||
expect(user.state).to eq('active')
|
||||
|
||||
user.labels.create(key: 'random', value: 'verified', scope: 'private')
|
||||
expect(user.state).to eq('active')
|
||||
|
||||
user.labels.last.destroy
|
||||
expect(user.state).to eq('active')
|
||||
|
||||
user.labels.find_by_key('phone').destroy
|
||||
expect(user.state).to eq('pending')
|
||||
end
|
||||
|
||||
it 'changes state when 2 label required' do
|
||||
# [phone documents] required
|
||||
expect(user.state).to eq('pending')
|
||||
|
||||
user.labels.create(key: 'phone', value: 'verified', scope: 'private')
|
||||
expect(user.state).to eq('pending')
|
||||
|
||||
user.labels.create(key: 'documents', value: 'verified', scope: 'private')
|
||||
expect(user.state).to eq('active')
|
||||
end
|
||||
|
||||
it 'changes state when one out of 3 label required' do
|
||||
# first or second third required
|
||||
expect(user.state).to eq('pending')
|
||||
|
||||
user.labels.create(key: 'first', value: 'verified', scope: 'private')
|
||||
expect(user.state).to eq('active_one_of_3_labels')
|
||||
|
||||
user.labels.find_by_key('first').destroy
|
||||
expect(user.state).to eq('pending')
|
||||
|
||||
user.labels.create(key: 'third', value: 'verified', scope: 'private')
|
||||
expect(user.state).to eq('active_one_of_3_labels')
|
||||
|
||||
user.labels.find_by_key('third').destroy
|
||||
expect(user.state).to eq('pending')
|
||||
|
||||
user.labels.create(key: 'second', value: 'verified', scope: 'private')
|
||||
expect(user.state).to eq('active_one_of_3_labels')
|
||||
end
|
||||
end
|
||||
|
||||
context 'not enough labels' do
|
||||
it 'doesnt change state if provided 1 out of 2 labels only' do
|
||||
# [phone documents] required
|
||||
expect(user.state).to eq('pending')
|
||||
|
||||
user.labels.create(key: 'documents', value: 'verified', scope: 'private')
|
||||
expect(user.state).to eq('pending')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'changing state on deleting' do
|
||||
context 'ALL policy' do
|
||||
let!(:give_user_active_state) do
|
||||
user.labels.create(key: 'phone', value: 'verified', scope: 'private')
|
||||
user.labels.create(key: 'documents', value: 'verified', scope: 'private')
|
||||
end
|
||||
|
||||
it 'recalculates from active to when remove all active labels' do
|
||||
expect(user.state).to eq('active')
|
||||
Label.find_by(key: 'documents', user: user).destroy
|
||||
Label.find_by(key: 'phone', user: user).destroy
|
||||
|
||||
user.reload
|
||||
|
||||
expect(user.state).to eq('pending')
|
||||
end
|
||||
|
||||
it 'recalculates from active_2_labels to active when pending one of active labels on ALL policy' do
|
||||
expect(user.state).to eq('active')
|
||||
Label.find_by(key: 'documents', user: user).destroy
|
||||
user.reload
|
||||
|
||||
expect(user.state).to eq('pending')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'testing workability if config is missing' do
|
||||
let!(:user) { create(:user, state: 'pending') }
|
||||
let(:reqs_list) {
|
||||
{
|
||||
"activation_requirements" => {
|
||||
"email" => "verified"
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
context 'not changing state on adding label' do
|
||||
it 'doesnt changes state if state_triggers config is missing' do
|
||||
expect(user.state).to eq('pending')
|
||||
|
||||
user.labels.create(key: 'trade', value: 'suspicious', scope: 'private')
|
||||
expect(user.state).to eq('pending')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'testing workability with ANY mapping type' do
|
||||
let!(:user) { create(:user, state: 'pending') }
|
||||
let(:reqs_list) {
|
||||
{
|
||||
"activation_requirements" => {
|
||||
"email" => "verified"
|
||||
},
|
||||
"state_triggers" => {
|
||||
"locked" => ['trade', 'withdraw']
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
context 'changing state on adding label' do
|
||||
context 'sucessfully' do
|
||||
it 'changes state when only when 1 label out of 2 matches' do
|
||||
expect(user.state).to eq('pending')
|
||||
|
||||
user.labels.create(key: 'trade', value: 'suspicious', scope: 'private')
|
||||
expect(user.state).to eq('locked')
|
||||
end
|
||||
end
|
||||
|
||||
context 'not enough labels' do
|
||||
it 'doesnt change state when no label matches' do
|
||||
expect(user.state).to eq('pending')
|
||||
user.labels.create(key: 'random', value: 'suspicious', scope: 'private')
|
||||
|
||||
expect(user.state).to eq('pending')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'changing state on deleting' do
|
||||
context 'ANY policy' do
|
||||
let!(:give_user_locked_state) do
|
||||
user.labels.create(key: 'trade', value: 'suspicious', scope: 'private')
|
||||
user.labels.create(key: 'withdraw', value: 'suspicious', scope: 'private')
|
||||
end
|
||||
|
||||
it 'doesnt recalculate state if remove one of ANY and another one of ANY still here with ANY policy' do
|
||||
expect(user.state).to eq('locked')
|
||||
|
||||
user.labels.find_by(key: 'trade').destroy
|
||||
user.reload
|
||||
|
||||
expect(user.state).to eq('locked')
|
||||
end
|
||||
|
||||
it 'recalculates if removed all of ANY and there is no more match' do
|
||||
expect(user.state).to eq('locked')
|
||||
|
||||
user.labels.find_by(key: 'trade').destroy
|
||||
user.labels.find_by(key: 'withdraw').destroy
|
||||
|
||||
user.reload
|
||||
expect(user.state).to eq('pending')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'event api behaviour' do
|
||||
let!(:user) { create(:user) }
|
||||
|
||||
context 'user updated' do
|
||||
before do
|
||||
allow(EventAPI).to receive(:notify)
|
||||
end
|
||||
|
||||
it 'receives event with change info' do
|
||||
user.update(level: 2)
|
||||
|
||||
expect(EventAPI).to have_received(:notify).with('model.user.updated',
|
||||
hash_including(
|
||||
changes: { level: 0 },
|
||||
record: hash_including(uid: user.uid, level: 2, email: user.email)
|
||||
))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user