# 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