Initial commit

This commit is contained in:
Yaser
2026-08-13 19:56:46 +03:30
commit de1d57a67b
474 changed files with 43185 additions and 0 deletions

409
spec/models/user_spec.rb Normal file
View 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