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

View File

@@ -0,0 +1,70 @@
# frozen_string_literal: true
describe Ability do
before do
allow(Ability).to receive(:admin_permissions).and_return({
"superadmin"=>{"manage"=>["User", "Activity", "Ability", "APIKey", "Profile", "Permission", "Label", "Restriction", "Level"]},
"admin"=>{"read"=>["Level", "APIKey", "Permission"], "manage"=>["User", "Activity", "Profile", "Label"]},
"compliance"=>{"read"=>["Level", "User", "Activity"], "manage"=>["Label"], "update"=>["Profile"]},
"support"=>{"read"=>["User", "Activity", "APIKey", "Profile", "Label", "Level"]}
})
end
let!(:create_permissions) do
create(:permission, role: 'superadmin', action: 'accept', verb: 'get')
create(:permission, role: 'admin', action: 'accept', verb: 'get')
create(:permission, role: 'compliance', action: 'accept', verb: 'get')
create(:permission, role: 'support', action: 'accept', verb: 'get')
end
context 'abilities for superadmin' do
let(:test_user) { create(:user, email: 'example@gmail.com', role: 'superadmin') }
subject(:ability) { AdminAbility.new(test_user) }
it { is_expected.to be_able_to(:manage, User.new) }
it { is_expected.to be_able_to(:manage, Activity.new) }
it { is_expected.to be_able_to(:manage, Profile.new) }
it { is_expected.to be_able_to(:manage, Permission.new) }
it { is_expected.to be_able_to(:manage, Label.new) }
it { is_expected.to be_able_to(:manage, Restriction.new) }
it { is_expected.to be_able_to(:manage, Level.new) }
end
context 'abilities for admin' do
let(:test_user) { create(:user, email: 'example@gmail.com', role: 'admin') }
subject(:ability) { AdminAbility.new(test_user) }
it { is_expected.to be_able_to(:read, Level.new) }
it { is_expected.to be_able_to(:read, APIKey.new) }
it { is_expected.to be_able_to(:read, Permission.new) }
it { is_expected.to be_able_to(:manage, User.new) }
it { is_expected.to be_able_to(:manage, Activity.new) }
it { is_expected.to be_able_to(:manage, Profile.new) }
it { is_expected.to be_able_to(:manage, Label.new) }
end
context 'abilities for compliance' do
let(:test_user) { create(:user, email: 'example@gmail.com', role: 'compliance') }
subject(:ability) { AdminAbility.new(test_user) }
it { is_expected.to be_able_to(:read, Level.new) }
it { is_expected.to be_able_to(:read, User.new) }
it { is_expected.to be_able_to(:read, Activity.new) }
it { is_expected.to be_able_to(:manage, Label.new) }
it { is_expected.to be_able_to(:update, Profile.new) }
end
context 'abilities for support' do
let(:test_user) { create(:user, email: 'example@gmail.com', role: 'support') }
subject(:ability) { AdminAbility.new(test_user) }
it { is_expected.to be_able_to(:read, User.new) }
it { is_expected.to be_able_to(:read, Activity.new) }
it { is_expected.to be_able_to(:read, APIKey.new) }
it { is_expected.to be_able_to(:read, Profile.new) }
it { is_expected.to be_able_to(:read, Label.new) }
it { is_expected.to be_able_to(:read, Level.new) }
end
end

View File

@@ -0,0 +1,65 @@
# frozen_string_literal: true
RSpec.describe Activity, type: :model do
let!(:create_admin_permission) do
create :permission,
role: 'admin'
end
let!(:create_member_permission) do
create :permission,
role: 'member'
end
let!(:activity) do
create :activity, topic: 'session',
action: 'login',
result: 'succeed',
user_agent: 'Magic Pony Browser'
end
context 'General' do
it { should belong_to(:user) }
it {
expect {
activity.update_attribute(:topic, 'otp')
}.to raise_error(ActiveRecord::ActiveRecordError, 'Activity is marked as readonly')
}
end
describe 'Validations' do
context 'Correct fields values' do
it { should allow_value('session').for(:topic) }
it { should allow_value('otp').for(:topic) }
it { should allow_value('password').for(:topic) }
it { should allow_value('succeed').for(:result) }
it { should allow_value('failed').for(:result) }
it { expect(activity.browser.ua).to eq 'Magic Pony Browser'}
end
context 'Banned actions and values' do
it { should_not allow_value('passed').for(:result) }
it { should_not allow_value('').for(:user_ip) }
it { expect(activity.browser.known?).to eq false }
it { expect(JSON.parse(activity.data)['note']).to eq 'Detected suspicious browser' }
end
end
describe 'Browser functionality' do
let(:valid_user_agent){'Android SDK 1.5r3: Mozilla/5.0 (Linux; U; Android 1.5; de-; sdk Build/CUPCAKE)
AppleWebkit/528.5+ (KHTML, like Gecko) Version/3.1.2 Mobile Safari/525.20.1'}
let!(:activity) do
create :activity, topic: 'session',
action: 'login',
result: 'succeed',
user_agent: valid_user_agent
end
context 'Detects browser information' do
it { expect(activity.browser.name).to eq 'Safari' }
it { expect(activity.browser.platform.android?).to eq true }
it { expect(activity.browser.webkit?).to eq true }
it { expect(activity.browser.full_version).to eq '3.1.2' }
it { expect(activity.browser.version).to eq '3' }
end
end
end

124
spec/models/api_key_spec.rb Normal file
View File

@@ -0,0 +1,124 @@
# frozen_string_literal: true
RSpec.describe APIKey, type: :model do
let!(:create_member_permission) do
create :permission,
role: 'member'
end
let!(:create_service_account_permission) do
create :permission,
role: 'service_account'
end
describe 'Validations' do
subject(:api_key) { build(:api_key, :with_user) }
it { should validate_presence_of(:secret).with_message(/can't be blank/) }
it { should validate_uniqueness_of(:kid).with_message(/has already been taken/) }
context 'key holder state' do
context 'valid response' do
context 'user with active state' do
let!(:user) { create(:user, state: 'active') }
it 'creates api key' do
subject.key_holder_account = user
expect(subject.save).to eq true
expect(subject.errors.full_messages).to eq []
end
end
context 'service account with active state' do
let!(:user) { create(:user, state: 'active') }
let!(:service_account) { create(:service_account, owner_id: user.id) }
it 'creates api key' do
subject.key_holder_account = user
expect(subject.save).to eq true
expect(subject.errors.full_messages).to eq []
end
end
end
context 'invalid response' do
subject { build(:api_key) }
context 'user with non active state' do
let!(:user) { create(:user, state: 'pending') }
it 'render error message' do
subject.key_holder_account = user
expect(subject.save).to eq false
expect(subject.errors.full_messages).to include(/non active state for key holder account/)
end
end
context 'service account with non active state' do
let!(:user) { create(:user, state: 'pending') }
let!(:service_account) { create(:service_account, owner_id: user.id) }
it 'render error message' do
subject.key_holder_account = service_account
expect(subject.save).to eq false
expect(subject.errors.full_messages).to include(/non active state for key holder account/)
end
end
end
end
context 'api key state on update' do
context 'valid response' do
context 'user with active state' do
let!(:user) { create(:user, state: 'active') }
let!(:api_key) { create(:api_key, key_holder_account: user, state: 'disabled') }
it 'updates api key state' do
api_key.state = 'active'
expect(api_key.save).to eq true
expect(api_key.errors.full_messages).to eq []
end
end
context 'service account with non active state' do
let!(:user) { create(:user, state: 'active') }
let!(:service_account) { create(:service_account, owner_id: user.id) }
let!(:api_key) { create(:api_key, key_holder_account: service_account, state: 'disabled') }
it 'render error message' do
api_key.state = 'active'
expect(api_key.save).to eq true
expect(api_key.errors.full_messages).to eq []
end
end
end
context 'invalid response' do
context 'user with non active state' do
let!(:user) { create(:user, state: 'active') }
let!(:api_key) { create(:api_key, key_holder_account: user) }
it 'render error message' do
user.update(state: 'banned')
api_key.state = 'active'
expect(api_key.save).to eq false
expect(api_key.errors.full_messages).to include(/cant activate api key with disabled key holder account/)
end
end
context 'service account with non active state' do
let!(:user) { create(:user, state: 'active') }
let!(:service_account) { create(:service_account, owner_id: user.id) }
let!(:api_key) { create(:api_key, key_holder_account: service_account) }
it 'render error message' do
service_account.update(state: 'disabled')
api_key.state = 'active'
expect(api_key.save).to eq false
expect(api_key.errors.full_messages).to include(/cant activate api key with disabled key holder account/)
end
end
end
end
end
end

View File

@@ -0,0 +1,108 @@
# frozen_string_literal: true
RSpec.describe Document, type: :model do
## Test of relationships
let!(:create_admin_permission) do
create :permission,
role: 'admin'
end
let!(:create_member_permission) do
create :permission,
role: 'member'
end
it { should belong_to(:user) }
describe 'validation' do
let!(:document) { build :document, doc_expire: doc_expire }
subject do
document.valid?
document.errors.messages
end
let(:doc_expire) { Date.current.to_s }
it { is_expected.to be_blank }
context 'when doc_expire is expired' do
let(:doc_expire) { 1.day.ago.to_s }
it { is_expected.to eq(doc_expire: ['is invalid']) }
end
end
context 'Document creation' do
let!(:current_user) { create(:user) }
let(:create_document) { create :document, user: current_user, doc_type: 'Passport', doc_category: 'front_side' }
let(:create_document_second) { create :document, user: current_user, doc_type: 'Passport', doc_category: 'Selfie' }
let(:create_without_label) { create :document, user: current_user, update_labels: false }
let(:document_label) { current_user.labels.first }
context 'when it is first document' do
it 'adds new document label' do
create_document
expect { create_document_second }.to change { current_user.reload.labels.count }.from(0).to(1)
end
it 'new document label is document: pending' do
create_document
create_document_second
expect(document_label.key).to eq 'document'
expect(document_label.value).to eq 'pending'
end
end
context 'when user has label document: rejected' do
let!(:document_label) do
create :label,
scope: 'private',
key: 'document',
value: 'rejected',
user: current_user
end
it 'does not add new label' do
create_document
expect { create_document_second }.to_not change { Label.count }
end
it 'changes label value to pending' do
create_document
create_document_second
expect(current_user.labels.first.value).to eq 'pending'
end
end
context 'when user has label document: verified' do
let!(:document_label) do
create :label,
scope: 'private',
key: 'document',
value: 'verified',
user: current_user
end
it 'does not add new label' do
expect { create_document }.to_not change { Label.count }
end
it 'remains value verified' do
expect { create_document }.to_not change { document_label }
end
end
end
context 'submasked fields' do
let!(:current_user) { create(:user) }
let(:document) { create :document, user: current_user, doc_type: 'Passport', doc_number: 'M0993353' }
let(:document_without_doc_number) { create :document, user: current_user, doc_type: 'Passport', doc_number: nil }
context 'number' do
it { expect(document.sub_masked_doc_number).to eq 'M0****53' }
it { expect(document_without_doc_number.sub_masked_doc_number).to eq nil }
it 'should mask first 2 letters and last 2 digits' do
document.update(doc_type: 'Driver license', doc_number: 'BO231283013DSAS23')
expect(document.sub_masked_doc_number).to eq 'BO*************23'
end
end
end
end

252
spec/models/label_spec.rb Normal file
View File

@@ -0,0 +1,252 @@
# frozen_string_literal: true
RSpec.describe Label, type: :model do
let!(:create_admin_permission) do
create :permission,
role: 'admin'
end
let!(:create_member_permission) do
create :permission,
role: 'member'
end
it { should belong_to(:user) }
describe 'update user level if label defined as level', order: :defined do
let!(:email_verified_level) { Level.find(1) }
let!(:phone_verified_level) { Level.find(2) }
let!(:identity_verified_level) { Level.find(3) }
let!(:document_verified_level) { Level.find(4) }
context 'when user has no labels' do
let!(:user) { create(:user) }
it { expect(user.reload.level).to eq 0 }
it 'does not change level if valid label has public scope' do
expect do
create_label_with_level(user, email_verified_level, scope: 'public')
end.to_not change { user.reload.level }
end
it 'when checks labels-levels mappings' do
expect do
create_label_with_level(user, email_verified_level)
end.to change { user.reload.level }.from(0).to(1)
expect do
create_label_with_level(user, phone_verified_level)
end.to change { user.reload.level }.from(1).to(2)
expect do
create_label_with_level(user, identity_verified_level)
end.to change { user.reload.level }.from(2).to(3)
expect do
create_label_with_level(user, document_verified_level)
end.to change { user.reload.level }.from(3).to(4)
end
end
context 'when user has verified email and phone' do
let!(:user) { create(:user) }
before do
create_label_with_level(user, email_verified_level)
create_label_with_level(user, phone_verified_level)
end
it 'changes to level 2 when identity verified label applied' do
expect(user.reload.level).to eq(2)
end
it 'changes to level 3 when identity verified label applied' do
expect do
create_label_with_level(user, identity_verified_level)
end.to change { user.reload.level }.to(3)
end
it 'downgrades level to 1 when phone state changes to rejected' do
Label.find_by(user: user, key: phone_verified_level.key).update(value: 'rejected')
user.update_level
expect(user.reload.level).to eq 1
end
it 'does not change level if user has document verified label' do
expect do
create_label_with_level(user, document_verified_level)
end.to_not change { user.reload.level }
end
end
context 'when user has all label required for level 4' do
let!(:user) { create(:user) }
before do
create_label_with_level(user, email_verified_level)
create_label_with_level(user, phone_verified_level)
create_label_with_level(user, identity_verified_level)
create_label_with_level(user, document_verified_level)
end
it { expect(user.reload.level).to eq 4 }
it 'downgrades level to 0 when email verified label changes' do
Label.find_by(user: user, key: email_verified_level.key).update(value: 'rejected')
user.update_level
expect(user.reload.level).to eq 0
end
it 'downgrades level to 0 when email verified label changes' do
Label.find_by(user: user, key: email_verified_level.key).destroy
user.update_level
expect(user.reload.level).to eq 0
end
end
context 'document label changes' do
let!(:user) { create(:user) }
let(:last_mailer_delivery) { ActionMailer::Base.deliveries.last }
let!(:document_label) do
create(
:label,
user: user,
key: 'document',
value: 'pending',
scope: 'private'
)
end
end
context 'when label scope is changed from private to public and reverse' do
let!(:user) { create(:user) }
before do
create_label_with_level(user, email_verified_level)
create_label_with_level(user, phone_verified_level)
create_label_with_level(user, identity_verified_level)
create_label_with_level(user, document_verified_level)
end
it 'updates level' do
expect do
user.labels.last.update(scope: :public)
end.to change { user.reload.level }.from(4).to(3)
expect do
user.labels.last.update(scope: :private)
end.to change { user.reload.level }.from(3).to(4)
end
end
context '2 labels with same keys' do
let!(:user) { create(:user) }
let!(:label_public) do
create :label,
user: user,
key: email_verified_level.key,
value: email_verified_level.value,
scope: 'public'
end
let!(:label_private) do
create :label,
user: user,
key: email_verified_level.key,
value: email_verified_level.value,
scope: 'private'
end
context 'can be created with different scopes' do
it 'user has both labels' do
expect(user.labels).to include(label_private, label_public)
end
it 'user has level 1' do
expect(user.level).to eq 1
end
context 'when private label changes' do
it 'user level downgrades when value changed' do
expect { label_private.update(value: 'rejected') }.to change { user.reload.level }.to 0
end
it 'user level downgrades when key changed' do
expect { label_private.update(key: 'email0') }.to change { user.reload.level }.to 0
end
end
context 'when public label changes' do
it 'user level does not change' do
expect { label_public.update(value: 'rejected') }.to_not change { user.reload.level }
end
end
end
end
context 'when user has all required labels for level 4 in wrong scope' do
let!(:user) { create(:user) }
let!(:label_email_public) do
create :label,
user: user,
key: email_verified_level.key,
value: email_verified_level.value,
scope: 'public'
end
let!(:label_phone_public) do
create :label,
user: user,
key: phone_verified_level.key,
value: phone_verified_level.value,
scope: 'public'
end
let!(:label_identity_public) do
create :label,
user: user,
key: identity_verified_level.key,
value: identity_verified_level.value,
scope: 'public'
end
let!(:label_document_public) do
create :label,
user: user,
key: document_verified_level.key,
value: document_verified_level.value,
scope: 'public'
end
it { expect(user.reload.level).to eq 0 }
end
end
context 'downcase fields' do
let(:user) { create(:user) }
let(:label) { build(:label, user: user, key: 'PhoNe', value: 'VeRifiEd') }
it 'downcases key and value before save' do
label.save
expect(label.reload.key).to eq 'phone'
expect(label.reload.value).to eq 'verified'
end
end
context 'event api behaviour' do
let!(:user) { create(:user, state: 'pending') }
let(:label) { create(:label, user_id: user.id) }
before do
allow(EventAPI).to receive(:notify)
end
it 'receives event with label create' do
label
expect(EventAPI).to have_received(:notify).with('model.label.created',
hash_including(
record: hash_including(
id: label.id,
key: label.key,
value: label.value,
user: hash_including(uid: user.uid, level: 0, email: user.email)
)
))
end
end
end

View File

@@ -0,0 +1,7 @@
# frozen_string_literal: true
RSpec.describe Level, type: :model do
it { should validate_presence_of(:key) }
it { should validate_presence_of(:value) }
it { should validate_presence_of(:description) }
end

41
spec/models/phone_spec.rb Normal file
View File

@@ -0,0 +1,41 @@
# frozen_string_literal: true
RSpec.describe Phone, type: :model do
let!(:create_member_permission) do
create :permission,
role: 'member'
end
context 'submasked fields' do
let!(:phone) { create(:phone) }
context 'number' do
it 'should mask country code and last 4 digits' do
phone.update(number: '79225551234')
expect(phone.sub_masked_number).to eq '7******1234'
end
it 'should mask country code and last 4 digits' do
phone.update(number: '+201112341923')
expect(phone.sub_masked_number).to eq '20******1923'
end
it 'should mask country code and last 4 digits' do
phone.update(number: '+380971232322')
expect(phone.sub_masked_number).to eq '380*****2322'
end
it 'should return empty phone number' do
phone.update(number: '')
expect(phone.sub_masked_number).to eq ''
end
context 'default country code' do
it 'should mask country code' do
phone.update_attribute(:number, '1112222')
expect(phone.sub_masked_number).to eq '11*2222'
end
end
end
end
end

385
spec/models/profile_spec.rb Normal file
View File

@@ -0,0 +1,385 @@
# frozen_string_literal: true
RSpec.describe Profile, type: :model do
describe 'squish_spaces' do
let!(:create_member_permission) do
create :permission,
role: 'member'
end
let!(:profile) do
create :profile, first_name: ' First Name ',
last_name: ' Last Name ',
city: ' New York ',
postcode: ' AB 135-144 '
end
it 'squishes spaces' do
profile.reload
expect(profile.first_name).to eq 'First Name'
expect(profile.last_name).to eq 'Last Name'
expect(profile.city).to eq 'New York'
expect(profile.postcode).to eq 'AB 135-144'
end
end
describe 'creating partial priofile' do
let!(:create_member_permission) do
create :permission,
role: 'member'
end
let!(:user) { create(:user) }
subject { Profile.create(params.merge(user: user)) }
context 'empty params' do
let!(:params) { {} }
it { expect(subject).to be_valid }
it { expect(subject.first_name.nil?).to be_truthy }
it { expect(subject.last_name.nil?).to be_truthy }
it { expect(subject.dob.nil?).to be_truthy }
it { expect(subject.address.nil?).to be_truthy }
it { expect(subject.postcode.nil?).to be_truthy }
it { expect(subject.city.nil?).to be_truthy }
it { expect(subject.country.nil?).to be_truthy }
it { expect(subject.metadata.nil?).to be_truthy }
it { expect(subject.state).to eq('drafted') }
it { expect(subject.user.labels.find_by(key: 'profile').value).to eq('drafted') }
context 'add empty params' do
let!(:params) {
{
last_name: Faker::Name.last_name,
first_name: Faker::Name.first_name,
dob: Faker::Date.birthday,
country: Faker::Address.country_code_long,
city: Faker::Address.city,
address: Faker::Address.street_address,
postcode: Faker::Address.zip_code
}
}
before do
subject.update(params)
end
it { expect(subject).to be_valid }
it { expect(subject.first_name.present?).to be_truthy }
it { expect(subject.last_name.present?).to be_truthy }
it { expect(subject.dob.present?).to be_truthy }
it { expect(subject.address.present?).to be_truthy }
it { expect(subject.postcode.present?).to be_truthy }
it { expect(subject.city.present?).to be_truthy }
it { expect(subject.country.present?).to be_truthy }
it { expect(subject.metadata.nil?).to be_truthy }
it { expect(subject.state).to eq('drafted') }
it { expect(subject.user.labels.find_by(key: 'profile').value).to eq('drafted') }
end
end
context 'all profile params' do
let!(:params) {
{
last_name: Faker::Name.last_name,
first_name: Faker::Name.first_name,
dob: Faker::Date.birthday,
country: Faker::Address.country_code_long,
city: Faker::Address.city,
address: Faker::Address.street_address,
postcode: Faker::Address.zip_code
}
}
it { expect(subject).to be_valid }
it { expect(subject.first_name.present?).to be_truthy }
it { expect(subject.last_name.present?).to be_truthy }
it { expect(subject.dob.present?).to be_truthy }
it { expect(subject.address.present?).to be_truthy }
it { expect(subject.postcode.present?).to be_truthy }
it { expect(subject.city.present?).to be_truthy }
it { expect(subject.country.present?).to be_truthy }
it { expect(subject.metadata.present?).to be_falsey }
it { expect(subject.state).to eq('drafted') }
it { expect(subject.user.labels.find_by(key: 'profile').value).to eq('drafted') }
end
end
context 'profile_state!' do
let!(:create_member_permission) do
create :permission,
role: 'member'
end
let!(:user) { create(:user) }
let!(:verified_profile) { create(:profile, user_id: user.id, state: 'verified') }
let!(:rejected_profile) { create(:profile, user_id: user.id, state: 'rejected') }
let!(:drafted_profile) { create(:profile, user_id: user.id, state: 'drafted') }
let!(:profile_params) {
{
user_id: user.id,
last_name: Faker::Name.last_name,
first_name: Faker::Name.first_name,
dob: Faker::Date.birthday,
country: Faker::Address.country_code_long,
city: Faker::Address.city,
address: Faker::Address.street_address,
postcode: Faker::Address.zip_code
}
}
it 'profile with state drafted' do
profile = Profile.new(profile_params)
profile.save
profile.valid?
expect(profile.errors[:state]).to eq(['already exists'])
end
it 'profile with state submitted' do
profile = Profile.new(profile_params.merge(state: 'submitted'))
profile.save
profile.valid?
expect(profile.errors[:state]).to eq(['already exists'])
end
it 'profile with state verified' do
profile = Profile.new(profile_params.merge(state: 'verified'))
profile.save
expect(profile.valid?).to eq true
end
it 'profile with state rejected' do
profile = Profile.new(profile_params.merge(state: 'rejected'))
profile.save
expect(profile.valid?).to eq true
end
end
context 'create_or_update_profile_label' do
let!(:create_member_permission) do
create :permission,
role: 'member'
end
let!(:user) { create(:user) }
let!(:profile_params) {
{
user_id: user.id,
last_name: Faker::Name.last_name,
first_name: Faker::Name.first_name,
dob: Faker::Date.birthday,
country: Faker::Address.country_code_long,
city: Faker::Address.city,
address: Faker::Address.street_address,
postcode: Faker::Address.zip_code
}
}
it 'creating profile label' do
expect(user.labels.count).to eq 0
Profile.create(profile_params)
expect(user.labels.count).to eq 1
expect(user.labels.first.key).to eq 'profile'
expect(user.labels.first.value).to eq 'drafted'
end
it 'updating profile label' do
profile = Profile.create(profile_params.merge(state: 'submitted'))
expect(user.labels.count).to eq 1
expect(user.labels.first.key).to eq 'profile'
expect(user.labels.first.value).to eq 'submitted'
expect(user.labels.count).to eq 1
profile.update(state: 'verified')
expect(user.labels.count).to eq 1
expect(user.labels.first.key).to eq 'profile'
expect(user.labels.first.value).to eq 'verified'
end
context 'dob param' do
let!(:profile) { create(:profile, user_id: user.id, state: 'verified') }
it 'should be valid dob' do
profile.update(dob: Time.now)
expect(profile.valid?).to eq true
end
it 'should be invalid dob format' do
profile.update(dob: '')
expect(profile.valid?).to eq false
expect(profile.errors[:dob]).to eq ["invalid date format"]
end
it 'should be invalid dob format' do
profile.update(dob: Time.now + 3.days)
expect(profile.valid?).to eq false
expect(profile.errors[:dob]).to eq ["cant be in future"]
end
end
end
context 'update_document_label' do
let!(:create_member_permission) do
create :permission,
role: 'member'
end
let!(:user) { create(:user) }
let!(:user_without_document) { create(:user) }
let!(:document_verified_level) { Level.find(4) }
let!(:document_verified_label) { create_label_with_level(user, document_verified_level) }
let!(:profile_params) {
{
last_name: Faker::Name.last_name,
first_name: Faker::Name.first_name,
dob: Faker::Date.birthday,
country: Faker::Address.country_code_long,
city: Faker::Address.city,
address: Faker::Address.street_address,
postcode: Faker::Address.zip_code
}
}
it 'change document state when new profile created' do
expect(user.labels.find_by(key: :document).value).to eq 'verified'
Profile.create(profile_params.merge(user_id: user.id))
expect(user.labels.count).to eq 2
expect(user.labels.find_by(key: :document).value).to eq 'verified'
end
it 'do not change document state when document doesnt exist' do
expect(user_without_document.labels.find_by(key: :document)).to eq nil
Profile.create(profile_params.merge(user_id: user_without_document.id))
expect(user_without_document.labels.count).to eq 1
expect(user_without_document.labels.find_by(key: :document)).to eq nil
end
end
context 'event api behaviour' do
let!(:permission) { create(:permission, role: 'member') }
let!(:user) { create(:user, state: 'pending', role: 'member') }
let!(:profile) { create(:profile, user_id: user.id, first_name: old_name) }
let!(:old_name) { Faker::Name.first_name }
let!(:new_name) { Faker::Name.first_name }
let(:profile_update) { profile.update(first_name: new_name ) }
before do
allow(EventAPI).to receive(:notify)
end
it 'receives event with label create' do
profile_update
expect(EventAPI).to have_received(:notify).with('model.profile.updated',
hash_including(
changes: { first_name: old_name },
record: hash_including(first_name: new_name)
))
end
end
context 'validation' do
let!(:create_member_permission) do
create :permission,
role: 'member'
end
context 'encrypted fields length' do
let!(:profile) { create(:profile) }
it 'encrypted first name should be valid with 255 characters' do
profile.update(first_name: Faker::Alphanumeric.alphanumeric(number: 255))
expect(profile.valid?).to eq true
end
it 'encrypted last name should be valid with 255 characters' do
profile.update(last_name: Faker::Alphanumeric.alphanumeric(number: 255))
expect(profile.valid?).to eq true
end
it 'encrypted address should be valid with 255 characters' do
profile.update(address: Faker::Alphanumeric.alphanumeric(number: 255))
expect(profile.valid?).to eq true
end
end
end
context 'submasked fields' do
let!(:create_member_permission) do
create :permission,
role: 'member'
end
let!(:user) { create(:user) }
let!(:profile) do
create :profile, first_name: 'Oleksandr',
last_name: 'Berezniy',
city: 'New York',
postcode: 'AB 135-144',
dob: Date.new(2007, 5, 12)
end
let!(:profile_without_last_name) do
create :profile, first_name: 'Oleksandr',
last_name: nil,
city: 'New York',
postcode: 'AB 135-144'
end
let!(:profile_without_dob) do
create :profile, first_name: 'Oleksandr',
last_name: nil,
city: 'New York',
postcode: 'AB 135-144',
dob: nil
end
context 'last_name' do
it { expect(profile.sub_masked_last_name).to eq 'B*******' }
it 'should mask all letters except first one' do
profile.update(last_name: 'Teylor_1')
expect(profile.sub_masked_last_name).to eq 'T*******'
end
it 'should mask all letters except first one' do
profile.update(last_name: ' Last name ')
expect(profile.sub_masked_last_name).to eq 'L********'
end
it 'should mask all letters except first one' do
profile.update(last_name: '')
expect(profile.sub_masked_last_name).to eq ''
end
it 'should mask all letters except first one' do
expect(profile_without_last_name.sub_masked_last_name).to eq nil
end
end
context 'dob' do
it { expect(profile.sub_masked_dob).to eq '2007-05-**' }
it 'should mask only date numbers' do
profile.update(dob: Date.new(2020, 12, 12))
expect(profile.sub_masked_dob).to eq '2020-12-**'
end
it 'should mask only date numbers' do
expect(profile_without_dob.sub_masked_dob).to eq nil
end
end
end
end

View File

@@ -0,0 +1,86 @@
# frozen_string_literal: true
RSpec.describe Restriction, type: :model do
context 'create' do
it { should_not allow_value('planet').for(:scope) }
it 'valid address with ip scope' do
expect(Restriction.new(scope: 'ip', value: '127.0.0.1', category: 'blacklist').valid?).to be_truthy
end
it 'invalid address with ip scope' do
expect(Restriction.new(scope: 'ip', value: 'abc.0.0.1', category: 'blacklist').valid?).to be_falsey
end
it 'ip subnet with ip scope' do
expect(Restriction.new(scope: 'ip', value: '127.0.0.1/24', category: 'blacklist').valid?).to be_falsey
end
it 'valid subnet with ip_subnet scope' do
expect(Restriction.new(scope: 'ip_subnet', value: '127.0.0.1/24', category: 'blacklist').valid?).to be_truthy
end
it 'invalid subnet with ip_subnet scope' do
expect(Restriction.new(scope: 'ip_subnet', value: '127.0.0.1/one', category: 'blacklist').valid?).to be_falsey
end
it 'ip address with ip_subnet scope' do
expect(Restriction.new(scope: 'ip_subnet', value: '127.0.0.1', category: 'blacklist').valid?).to be_falsey
end
end
context 'session destroy' do
let!(:permission) { create :permission, role: 'member'}
let(:user) { create(:user) }
before do
allow(Rails.cache).to receive(:delete_matched).and_return(nil)
end
context 'blocklogin category' do
context 'after create' do
it do
expect(Rails.cache).to receive(:delete_matched)
Restriction.create!(scope: 'ip', value: '127.0.0.1', category: 'blocklogin', state: "enabled")
end
it do
expect(Rails.cache).to_not receive(:delete_matched)
Restriction.create!(scope: 'ip', value: '127.0.0.2', category: 'blocklogin', state: "disabled")
end
end
context 'after update' do
let!(:enabled_restriction) {create(:restriction, scope: 'ip', value: '127.0.0.3', category: 'blocklogin', state: "enabled")}
let!(:disabled_restriction) {create( :restriction, scope: 'ip', value: '127.0.0.4', category: 'blocklogin', state: "disabled")}
it do
expect(Rails.cache).to receive(:delete_matched)
disabled_restriction.update(state: "enabled")
end
it do
expect(Rails.cache).to_not receive(:delete_matched)
enabled_restriction.update(state: "enabled")
end
it do
expect(Rails.cache).to_not receive(:delete_matched)
disabled_restriction.update(state: "disabled")
end
it do
expect(Rails.cache).to_not receive(:delete_matched)
enabled_restriction.update(state: "disabled")
end
end
end
context 'another category' do
it 'it should not destroy sessions' do
expect(Rails.cache).to_not receive(:delete_matched)
Restriction.create!(scope: 'ip', value: '127.0.0.1', category: 'blacklist', state: "enabled")
end
end
end
end

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