Files
Dalan/spec/api/v2/resource/profiles_spec.rb
2026-08-13 19:56:46 +03:30

573 lines
21 KiB
Ruby
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# frozen_string_literal: true
describe 'API::V2::Resource::Profiles' do
before { allow(Barong::App.config).to receive_messages(kyc_provider: 'local') }
include_context 'bearer authentication'
let!(:create_member_permission) do
create :permission,
role: 'member'
end
let!(:optional_params) do
{
metadata: {
gender: Faker::Creature::Dog.gender,
place_of_birth: Faker::Address.city
}.to_json
}
end
describe 'POST /api/v2/resource/profiles' do
describe 'KYC verification' do
let!(:request_params) do
{
last_name: Faker::Name.last_name,
first_name: Faker::Name.first_name,
dob: Faker::Date.birthday,
country: Faker::Address.country_code,
city: Faker::Address.city,
address: Faker::Address.state,
postcode: Faker::Address.zip_code
}
end
let!(:url) { '/api/v2/resource/profiles' }
it 'triggers KycService' do
expect(KycService).to receive(:profile_step)
post url, params: request_params, headers: auth_header
expect(response.status).to eq(201)
end
context 'Local verification' do
before { allow(Barong::App.config).to receive_messages(kyc_provider: 'local') }
it 'adds a label for first verification' do
expect(test_user.labels).to eq([])
post url, params: request_params, headers: auth_header
expect(test_user.reload.labels.count).to eq(1)
expect(test_user.reload.labels.first.key).to eq('profile')
expect(test_user.reload.labels.first.value).to eq('drafted')
end
it 'doesnt trigger KYCAID worker' do
expect(KycService).to receive(:profile_step)
expect(KYC::Kycaid::ApplicantWorker).not_to receive(:perform_async)
post url, params: request_params, headers: auth_header
expect(response.status).to eq(201)
end
it 'updates label on re-submit' do
expect(test_user.labels).to eq([])
post url, params: request_params, headers: auth_header
expect(test_user.reload.labels.count).to eq(1)
expect(test_user.reload.labels.first.key).to eq('profile')
expect(test_user.reload.labels.first.value).to eq('drafted')
put url, params: request_params.merge(confirm: true), headers: auth_header
expect(test_user.reload.labels.count).to eq(1)
expect(test_user.reload.labels.first.key).to eq('profile')
expect(test_user.reload.labels.first.value).to eq('submitted')
end
end
context 'KYCAID verification' do
before { allow(Barong::App.config).to receive_messages(kyc_provider: 'kycaid') }
it 'adds a label for first verification' do
expect(test_user.labels).to eq([])
post url, params: request_params, headers: auth_header
expect(test_user.reload.labels.count).to eq(1)
expect(test_user.reload.labels.first.key).to eq('profile')
expect(test_user.reload.labels.first.value).to eq('drafted')
end
it 'updates label on re-submit' do
expect(test_user.labels).to eq([])
post url, params: request_params, headers: auth_header
expect(test_user.reload.labels.count).to eq(1)
expect(test_user.reload.labels.first.key).to eq('profile')
expect(test_user.reload.labels.first.value).to eq('drafted')
put url, params: request_params.merge(confirm: true), headers: auth_header
expect(test_user.reload.labels.count).to eq(1)
expect(test_user.reload.labels.first.key).to eq('profile')
expect(test_user.reload.labels.first.value).to eq('submitted')
end
it 'triggers KYCAID worker on submitted state' do
expect(KYC::Kycaid::ApplicantWorker).to receive(:perform_async)
post url, params: request_params.merge(confirm: true), headers: auth_header
expect(response.status).to eq(201)
end
it 'doesnt trigger KYCAID worker on drafted state' do
expect(KYC::Kycaid::ApplicantWorker).not_to receive(:perform_async)
post url, params: request_params, headers: auth_header
expect(response.status).to eq(201)
end
it 'doesnt trigger KYCAID worker on rejected state' do
post url, params: request_params.merge(confirm: true), headers: auth_header
expect(response.status).to eq(201)
expect(KYC::Kycaid::ApplicantWorker).not_to receive(:perform_async)
test_user.reload.profiles.last.update(state: 'rejected')
end
it 'doesnt trigger KYCAID worker on verified state' do
post url, params: request_params.merge(confirm: true), headers: auth_header
expect(response.status).to eq(201)
expect(KYC::Kycaid::ApplicantWorker).not_to receive(:perform_async)
test_user.reload.profiles.last.update(state: 'verified')
end
end
end
let!(:url) { '/api/v2/resource/profiles' }
let!(:user_info) { '/api/v2/resource/users/me' }
let!(:request_params) do
{
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.state,
postcode: Faker::Address.zip_code
}
end
let!(:asian_params) do
{
last_name: "",
first_name: "채원",
dob: Faker::Date.birthday,
country: Faker::Address.country_code_long,
city: "안산시",
address: "사직로3길 23",
postcode: Faker::Address.zip_code
}
end
it 'accept / , ; in address' do
request_params[:address] = '28/2 Kevin Brook; Miami, USA'
expect { post url, params: request_params, headers: auth_header }
.to change { Profile.count }.by (1)
expect(response.status).to eq(201)
res = json_body
expect(res[:address]).to eq request_params[:address]
end
it 'accept . in address' do
request_params[:address] = 'Larkin Fork.South, New York/AP'
expect { post url, params: request_params, headers: auth_header }
.to change { Profile.count }.by (1)
expect(response.status).to eq(201)
res = json_body
expect(res[:address]).to eq request_params[:address]
end
it 'accept # ~ \ : " & ( ) in address' do
request_params[:address] = '28~1/2 \"Kevin & Brook": (Miami, USA)'
expect { post url, params: request_params, headers: auth_header }
.to change { Profile.count }.by (1)
expect(response.status).to eq(201)
res = json_body
expect(res[:address]).to eq request_params[:address]
end
it "accept ' in address" do
request_params[:address] = "'Larkin Fork' South New York"
expect { post url, params: request_params, headers: auth_header }
.to change { Profile.count }.by (1)
expect(response.status).to eq(201)
res = json_body
expect(res[:address]).to eq request_params[:address]
end
it "accept in address" do
request_params[:address] = "'LarkinFork' South New York"
expect { post url, params: request_params, headers: auth_header }
.to change { Profile.count }.by (1)
expect(response.status).to eq(201)
res = json_body
expect(res[:address]).to eq request_params[:address]
end
it "doesn't accept @ in address" do
request_params[:address] = "'LarkinFork' @South New York"
expect { post url, params: request_params, headers: auth_header }
.not_to change { Profile.count }
expect(response.status).to eq(422)
end
it 'accept . in city' do
request_params[:city] = 'St. Petersburg'
expect { post url, params: request_params, headers: auth_header }
.to change { Profile.count }.by (1)
expect(response.status).to eq(201)
res = json_body
expect(res[:city]).to eq request_params[:city]
end
it 'accept dash in city' do
request_params[:city] = 'HubliDharwad'
expect { post url, params: request_params, headers: auth_header }
.to change { Profile.count }.by (1)
expect(response.status).to eq(201)
res = json_body
expect(res[:city]).to eq request_params[:city]
end
it 'accept hyphen in city' do
request_params[:city] = 'Hubli-Dharwad'
expect { post url, params: request_params, headers: auth_header }
.to change { Profile.count }.by (1)
expect(response.status).to eq(201)
res = json_body
expect(res[:city]).to eq request_params[:city]
end
it 'accept \' in city' do
request_params[:city] = 'Cava de\' Tirreni'
expect { post url, params: request_params, headers: auth_header }
.to change { Profile.count }.by (1)
expect(response.status).to eq(201)
res = json_body
expect(res[:city]).to eq request_params[:city]
end
it "doesn't accept # in city" do
request_params[:city] = 'Cava de\' #Tirreni'
expect { post url, params: request_params, headers: auth_header }
.not_to change { Profile.count }
expect(response.status).to eq(422)
end
it "doesn't accept @ in city" do
request_params[:city] = 'Cava de\' @Tirreni'
expect { post url, params: request_params, headers: auth_header }
.not_to change { Profile.count }
expect(response.status).to eq(422)
end
it 'creates new profile with only required fields' do
expect { post url, params: request_params, headers: auth_header }
.to change { Profile.count }.by (1)
expect(response.status).to eq(201)
res = json_body
expect(res[:last_name]).to eq request_params[:last_name].sub(/(?<=\A.{1})(.*)/) { |match| '*' * match.length }
expect(res[:first_name]).to eq request_params[:first_name]
expect(res[:dob]).to eq request_params[:dob].to_s.sub(/(?<=\A.{8})(.*)/) { |match| '*' * match.length }
expect(res[:country]).to eq request_params[:country]
expect(res[:city]).to eq request_params[:city]
expect(res[:address]).to eq request_params[:address]
expect(res[:postcode]).to eq request_params[:postcode]
expect(res[:metadata]).to be_blank
end
it 'creates new profile with only required fields without masking' do
Barong::App.config.stub(:api_data_masking_enabled).and_return(false)
expect { post url, params: request_params, headers: auth_header }
.to change { Profile.count }.by (1)
expect(response.status).to eq(201)
res = json_body
expect(res[:last_name]).to eq request_params[:last_name]
expect(res[:first_name]).to eq request_params[:first_name]
expect(res[:dob]).to eq request_params[:dob].to_s
expect(res[:country]).to eq request_params[:country]
expect(res[:city]).to eq request_params[:city]
expect(res[:address]).to eq request_params[:address]
expect(res[:postcode]).to eq request_params[:postcode]
expect(res[:metadata]).to be_blank
end
it 'creates new profile with corean symbols fields' do
expect { post url, params: asian_params, headers: auth_header }
.to change { Profile.count }.by (1)
expect(response.status).to eq(201)
res = json_body
expect(res[:last_name]).to eq asian_params[:last_name]
expect(res[:first_name]).to eq asian_params[:first_name]
expect(res[:dob]).to eq asian_params[:dob].to_s.sub(/(?<=\A.{8})(.*)/) { |match| '*' * match.length }
expect(res[:country]).to eq asian_params[:country]
expect(res[:city]).to eq asian_params[:city]
expect(res[:address]).to eq asian_params[:address]
expect(res[:postcode]).to eq asian_params[:postcode]
expect(res[:metadata]).to be_blank
end
it 'creates new profile with all metadata fields' do
expect { post url, params: request_params.merge(optional_params), headers: auth_header }
.to change { Profile.count }.by (1)
expect(response.status).to eq(201)
res = json_body
expect(res[:metadata]).to eq(optional_params[:metadata])
end
it 'renders an error if metadata is not json' do
expect { post url, params: request_params.merge({ metadata: '{ bar: baz }' }), headers: auth_header }
.not_to change { Profile.count }
expect_status_to_eq 422
expect_body.to eq(errors: ["metadata.invalid_format"])
end
context 'create another one profile with state drafted' do
before do
post url, params: request_params.merge(optional_params), headers: auth_header
end
it 'doesn\'t create new profile' do
post url, params: request_params.merge(optional_params), headers: auth_header
result = json_body
expect(*result[:errors]).to eq('state.exists')
end
end
context 'create another one profile with state submitted' do
before do
post url, params: request_params.merge(optional_params, confirm: true), headers: auth_header
end
it 'doesn\'t create new profile' do
post url, params: request_params.merge(optional_params, confirm: true), headers: auth_header
result = json_body
expect(*result[:errors]).to eq('state.exists')
end
end
context 'create another one profile with state submitted and drafted' do
before do
post url, params: request_params.merge(optional_params, confirm: true), headers: auth_header
end
it 'doesn\'t create new profile' do
post url, params: request_params.merge(optional_params), headers: auth_header
result = json_body
expect(*result[:errors]).to eq('state.exists')
end
end
context 'partial creating profile' do
context 'empty params' do
it 'returns profile' do
expect { post url, params: {}, headers: auth_header }
.to change { Profile.count }.by (1)
expect(response.status).to eq(201)
expect(json_body[:state]).to eq('drafted')
expect(json_body[:metadata].blank?).to be_truthy
Profile::OPTIONAL_PARAMS.each { |p|
expect(json_body[p].blank?).to be_truthy
}
Profile::OPTIONAL_PARAMS.each { |p|
expect(json_body.with_indifferent_access[p].blank?).to be_truthy
}
expect(Profile.last.user.labels.find_by(key: 'profile').value).to eq('drafted')
end
end
context 'several params' do
let(:params) { { last_name: Faker::Name.last_name, first_name: Faker::Name.first_name } }
it 'returns profile' do
expect { post url, params: params, headers: auth_header }
.to change { Profile.count }.by (1)
expect(response.status).to eq(201)
expect(json_body[:first_name].nil?).to be_falsey
expect(json_body[:last_name].nil?).to be_falsey
expect(json_body[:state]).to eq('drafted')
expect(json_body[:metadata].blank?).to be_truthy
(Profile::OPTIONAL_PARAMS - params.stringify_keys.keys).each { |p|
expect(json_body.with_indifferent_access[p].blank?).to be_truthy
}
expect(Profile.last.user.labels.find_by(key: :profile).value).to eq('drafted')
end
end
context 'several params with profile confirmation' do
let(:params) { { last_name: Faker::Name.last_name, first_name: Faker::Name.first_name } }
it 'returns profile' do
expect { post url, params: params.merge(confirm: true), headers: auth_header }
.to change { Profile.count }.by (1)
expect(response.status).to eq(201)
expect(json_body[:first_name].nil?).to be_falsey
expect(json_body[:last_name].nil?).to be_falsey
expect(json_body[:state]).to eq('submitted')
expect(json_body[:metadata].blank?).to be_truthy
(Profile::OPTIONAL_PARAMS - params.stringify_keys.keys).each { |p|
expect(json_body.with_indifferent_access[p].blank?).to be_truthy
}
expect(Profile.last.user.labels.find_by(key: :profile).value).to eq('submitted')
end
end
context 'full profile params' do
it 'returns profile' do
expect { post url, params: request_params, headers: auth_header }
.to change { Profile.count }.by (1)
expect(response.status).to eq(201)
expect(json_body[:state]).to eq('drafted')
expect(json_body[:metadata].blank?).to be_truthy
request_params.keys.each { |p|
expect(json_body[p].present?).to be_truthy
}
expect(Profile.last.user.labels.find_by(key: 'profile').value).to eq('drafted')
end
end
end
end
describe 'GET /api/v2/resource/profiles/me' do
let!(:url) { '/api/v2/resource/profiles/me' }
let!(:request_params) do
{
first_name: Faker::Name.first_name,
last_name: Faker::Name.last_name,
dob: Faker::Date.birthday,
address: Faker::Address.state,
postcode: Faker::Address.zip_code,
city: Faker::Address.city,
country: Faker::Address.country_code_long
}
end
it 'returns user profile data with metadata' do
post '/api/v2/resource/profiles', params: request_params.merge(optional_params),
headers: auth_header
expect(response.status).to eq(201)
get url, headers: auth_header
expect(response.status).to eq(200)
last_name = request_params[:last_name].sub(/(?<=\A.{1})(.*)/) { |match| '*' * match.length }
dob = request_params[:dob].to_s.sub(/(?<=\A.{8})(.*)/) { |match| '*' * match.length }
expected_json = request_params.merge(state: 'drafted', last_name: last_name,dob: dob).merge(optional_params).to_json
expect(JSON.parse(response.body)[0].except('created_at', 'updated_at')).to eq(JSON.parse(expected_json))
end
end
context 'event API behavior' do
let!(:url) { '/api/v2/resource/profiles' }
let!(:request_params) do
{
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.state,
postcode: Faker::Address.zip_code
}
end
before do
allow(EventAPI).to receive(:notify)
end
it 'receive model.profile.created notify' do
expect(EventAPI).to receive(:notify).ordered.with('model.user.created', hash_including(:record))
expect(EventAPI).to receive(:notify).ordered.with('model.profile.created', hash_including(:record))
post url, params: request_params, headers: auth_header
end
it 'receive model.profile.created notify with user and profile params' do
expect(EventAPI).to receive(:notify).ordered.with('model.user.created', hash_including(:record))
expect(EventAPI).to receive(:notify).ordered.with(
'model.profile.created',
hash_including(
record: {
user: anything,
address: anything,
city: anything,
country: anything,
created_at: anything,
updated_at: anything,
dob: anything,
first_name: anything,
last_name: anything,
postcode: anything
}
)
)
post url, params: request_params, headers: auth_header
end
end
describe 'PUT /api/v2/resource/profiles' do
let!(:url) { '/api/v2/resource/profiles' }
let!(:request_params) do
{
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
}
end
context 'user without profile' do
it 'renders an error when profile doesnt exist' do
put url, params: request_params, headers: auth_header
expect_status.to eq(404)
expect_body.to eq(errors: ['resource.profile.doesnt_exist_or_not_editable'])
end
end
context 'user with profile' do
let!(:profile) { create(:profile, user: test_user)}
it 'returns submitted profile' do
expect { put url, params: request_params.merge(confirm: true), headers: auth_header }
.not_to change { Profile.count }
expect(response.status).to eq(200)
expect(json_body[:state]).to eq('submitted')
expect(profile[:metadata]).to be_blank
end
end
context 'user with partial profile' do
let!(:profile) { create(:profile, user: test_user, last_name: nil, first_name: nil) }
it 'returns partial profile' do
expect { put url, params: request_params.except(:first_name), headers: auth_header }
.not_to change { Profile.count }
expect(response.status).to eq(200)
expect(json_body[:state]).to eq('drafted')
expect(json_body[:metadata]).to be_blank
end
it 'returns completed profile' do
expect { put url, params: request_params, headers: auth_header }
.not_to change { Profile.count }
expect(response.status).to eq(200)
expect(json_body[:state]).to eq('drafted')
expect(json_body[:metadata]).to be_blank
end
end
end
end