Initial commit
This commit is contained in:
374
spec/api/v2/management/api_keys_spec.rb
Normal file
374
spec/api/v2/management/api_keys_spec.rb
Normal file
@@ -0,0 +1,374 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
describe API::V2::Management::APIKeys, type: :request do
|
||||
before do
|
||||
defaults_for_management_api_v2_security_configuration!
|
||||
management_api_v2_security_configuration.merge! \
|
||||
scopes: {
|
||||
write_apikeys: { permitted_signers: %i[alex jeff], mandatory_signers: %i[alex] },
|
||||
}
|
||||
end
|
||||
|
||||
let!(:create_admin_permission) do
|
||||
create :permission,
|
||||
role: 'admin'
|
||||
end
|
||||
|
||||
let!(:create_member_permission) do
|
||||
create :permission,
|
||||
role: 'member'
|
||||
end
|
||||
|
||||
let!(:create_service_account_permission) do
|
||||
create :permission,
|
||||
role: 'service_account'
|
||||
end
|
||||
|
||||
describe 'POST /api_keys' do
|
||||
let(:signers) { %i[alex jeff] }
|
||||
let(:data) { params.merge(scope: :write_apikeys) }
|
||||
|
||||
let(:do_request) do
|
||||
post_json '/api/v2/management/api_keys',
|
||||
multisig_jwt_management_api_v2({ data: data }, *signers)
|
||||
end
|
||||
|
||||
let(:params) do
|
||||
api_keys_params
|
||||
end
|
||||
|
||||
context 'valid request' do
|
||||
context 'service account' do
|
||||
before do
|
||||
allow(Barong::App.config).to receive_messages(mgn_api_keys_sa: true)
|
||||
end
|
||||
|
||||
let!(:service_account) { create(:service_account) }
|
||||
|
||||
let(:api_keys_params) do
|
||||
{
|
||||
uid: service_account.uid,
|
||||
algorithm: 'HS256',
|
||||
scopes: 'trade'
|
||||
}
|
||||
end
|
||||
|
||||
it 'creates a api key' do
|
||||
do_request
|
||||
expect(response.status).to eq(201)
|
||||
|
||||
result = JSON.parse(response.body)
|
||||
expect(result.keys).to match_array %w[kid algorithm scope state secret created_at updated_at]
|
||||
expect(result['state']).to eq service_account.state
|
||||
expect(result['scope']).to eq ['trade']
|
||||
expect(result['algorithm']).to eq 'HS256'
|
||||
end
|
||||
end
|
||||
|
||||
context 'user' do
|
||||
before do
|
||||
allow(Barong::App.config).to receive_messages(mgn_api_keys_user: true)
|
||||
end
|
||||
|
||||
let!(:user) { create(:user) }
|
||||
|
||||
let(:api_keys_params) do
|
||||
{
|
||||
uid: user.uid,
|
||||
algorithm: 'HS256',
|
||||
scopes: 'trade'
|
||||
}
|
||||
end
|
||||
|
||||
it 'creates a api key' do
|
||||
do_request
|
||||
expect(response.status).to eq(201)
|
||||
|
||||
result = JSON.parse(response.body)
|
||||
expect(result.keys).to match_array %w[kid algorithm scope state secret created_at updated_at]
|
||||
expect(result['state']).to eq user.state
|
||||
expect(result['scope']).to eq ['trade']
|
||||
expect(result['algorithm']).to eq 'HS256'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'invalid request' do
|
||||
context 'vault inaccessible' do
|
||||
before do
|
||||
allow(Barong::App.config).to receive_messages(mgn_api_keys_sa: true)
|
||||
end
|
||||
|
||||
let!(:service_account) { create(:service_account) }
|
||||
let(:api_keys_params) do
|
||||
{
|
||||
uid: service_account.uid,
|
||||
algorithm: 'HS256',
|
||||
scopes: 'trade'
|
||||
}
|
||||
end
|
||||
|
||||
it 'should raise an error' do
|
||||
allow(Vault::Rails).to receive(:encrypt).and_raise(Vault::VaultError)
|
||||
do_request
|
||||
expect(response.status).to eq(422)
|
||||
expect_body.to eq(errors: ["api_key.could_not_save_secret"])
|
||||
end
|
||||
end
|
||||
|
||||
context 'service account doesnt exist' do
|
||||
before do
|
||||
allow(Barong::App.config).to receive_messages(mgn_api_keys_sa: true)
|
||||
end
|
||||
|
||||
let(:api_keys_params) do
|
||||
{
|
||||
uid: ServiceAccount::UID_PREFIX + 'random',
|
||||
algorithm: 'HS256',
|
||||
scopes: 'trade'
|
||||
}
|
||||
end
|
||||
|
||||
it 'should raise an error' do
|
||||
do_request
|
||||
expect(response.status).to eq(422)
|
||||
expect_body.to eq(error: 'service_account_doesnt_exist')
|
||||
end
|
||||
end
|
||||
|
||||
context 'user doesnt exists' do
|
||||
before do
|
||||
allow(Barong::App.config).to receive_messages(mgn_api_keys_user: true)
|
||||
end
|
||||
|
||||
let(:api_keys_params) do
|
||||
{
|
||||
uid: UIDGenerator.generate(Barong::App.config.uid_prefix),
|
||||
algorithm: 'HS256',
|
||||
scopes: 'trade'
|
||||
}
|
||||
end
|
||||
|
||||
it 'should raise an error' do
|
||||
do_request
|
||||
expect(response.status).to eq(422)
|
||||
expect_body.to eq(error: 'user_doesnt_exist')
|
||||
end
|
||||
end
|
||||
|
||||
context 'algorithm is invalid' do
|
||||
before do
|
||||
allow(Barong::App.config).to receive_messages(mgn_api_keys_sa: true)
|
||||
end
|
||||
|
||||
let!(:service_account) { create(:service_account) }
|
||||
let(:api_keys_params) do
|
||||
{
|
||||
uid: service_account.uid,
|
||||
algorithm: 'random',
|
||||
scopes: 'trade'
|
||||
}
|
||||
end
|
||||
|
||||
it 'should raise an error' do
|
||||
do_request
|
||||
expect(response.status).to eq(422)
|
||||
expect_body.to eq(errors: ['kid.blank', 'algorithm.inclusion'])
|
||||
end
|
||||
end
|
||||
|
||||
context 'disabled endpoint' do
|
||||
let(:api_keys_params) do
|
||||
{
|
||||
uid: UIDGenerator.generate(Barong::App.config.uid_prefix),
|
||||
algorithm: 'HS256',
|
||||
scopes: 'trade'
|
||||
}
|
||||
end
|
||||
|
||||
it 'should raise an error' do
|
||||
do_request
|
||||
expect(response.status).to eq(422)
|
||||
expect_body.to eq(error: 'disabled_management_endpoint')
|
||||
end
|
||||
end
|
||||
|
||||
context 'unexisting uid' do
|
||||
|
||||
let(:api_keys_params) do
|
||||
{
|
||||
uid: 'random',
|
||||
algorithm: 'HS256',
|
||||
scopes: 'trade'
|
||||
}
|
||||
end
|
||||
|
||||
it 'should raise an error' do
|
||||
do_request
|
||||
expect(response.status).to eq(422)
|
||||
expect_body.to eq(error: 'uid_prefix_doesnt_exist')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'POST /api_keys/update' do
|
||||
let(:signers) { %i[alex jeff] }
|
||||
let(:data) { params.merge(scope: :write_apikeys) }
|
||||
|
||||
let(:do_request) do
|
||||
post_json '/api/v2/management/api_keys/update',
|
||||
multisig_jwt_management_api_v2({ data: data }, *signers)
|
||||
end
|
||||
|
||||
let(:params) do
|
||||
api_keys_params
|
||||
end
|
||||
|
||||
let!(:api_key) { create(:api_key, :with_service_account) }
|
||||
|
||||
context 'valid request' do
|
||||
context 'user' do
|
||||
let!(:api_key) { create(:api_key, :with_user) }
|
||||
|
||||
before do
|
||||
allow(Barong::App.config).to receive_messages(mgn_api_keys_user: true)
|
||||
end
|
||||
|
||||
let(:params) do
|
||||
{
|
||||
uid: api_key.key_holder_account.uid,
|
||||
kid: api_key.kid,
|
||||
state: 'inactive',
|
||||
scopes: 'sell'
|
||||
}
|
||||
end
|
||||
|
||||
it 'updates api key' do
|
||||
do_request
|
||||
expect(response.status).to eq(201)
|
||||
|
||||
result = JSON.parse(response.body)
|
||||
expect(result.keys).to match_array %w[kid algorithm scope state created_at updated_at]
|
||||
expect(result['state']).to eq 'inactive'
|
||||
expect(result['scope']).to eq ['sell']
|
||||
end
|
||||
end
|
||||
|
||||
context 'service account' do
|
||||
before do
|
||||
allow(Barong::App.config).to receive_messages(mgn_api_keys_sa: true)
|
||||
end
|
||||
|
||||
let(:params) do
|
||||
{
|
||||
uid: api_key.key_holder_account.uid,
|
||||
kid: api_key.kid,
|
||||
state: 'inactive',
|
||||
scopes: 'sell'
|
||||
}
|
||||
end
|
||||
|
||||
it 'updates api key' do
|
||||
do_request
|
||||
expect(response.status).to eq(201)
|
||||
|
||||
result = JSON.parse(response.body)
|
||||
expect(result.keys).to match_array %w[kid algorithm scope state created_at updated_at]
|
||||
expect(result['state']).to eq 'inactive'
|
||||
expect(result['scope']).to eq ['sell']
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'invalid request' do
|
||||
context 'api keys doesnt exist' do
|
||||
before do
|
||||
allow(Barong::App.config).to receive_messages(mgn_api_keys_sa: true)
|
||||
end
|
||||
|
||||
let(:api_keys_params) do
|
||||
{
|
||||
uid: api_key.key_holder_account.uid,
|
||||
kid: 'random kid'
|
||||
}
|
||||
end
|
||||
|
||||
it 'should raise an error' do
|
||||
do_request
|
||||
expect(response.status).to eq(422)
|
||||
expect_body.to eq(error: 'api_key_doesnt_exist')
|
||||
end
|
||||
end
|
||||
|
||||
context 'service account doesnt exist' do
|
||||
before do
|
||||
allow(Barong::App.config).to receive_messages(mgn_api_keys_sa: true)
|
||||
end
|
||||
|
||||
let(:api_keys_params) do
|
||||
{
|
||||
uid: ServiceAccount::UID_PREFIX + 'random',
|
||||
kid: api_key.kid
|
||||
}
|
||||
end
|
||||
|
||||
it 'should raise an error' do
|
||||
do_request
|
||||
expect(response.status).to eq(422)
|
||||
expect_body.to eq(error: 'service_account_doesnt_exist')
|
||||
end
|
||||
end
|
||||
|
||||
context 'user doesnt exist' do
|
||||
before do
|
||||
allow(Barong::App.config).to receive_messages(mgn_api_keys_user: true)
|
||||
end
|
||||
|
||||
let(:api_keys_params) do
|
||||
{
|
||||
uid: UIDGenerator.generate(Barong::App.config.uid_prefix),
|
||||
kid: api_key.kid
|
||||
}
|
||||
end
|
||||
|
||||
it 'should raise an error' do
|
||||
do_request
|
||||
expect(response.status).to eq(422)
|
||||
expect_body.to eq(error: 'user_doesnt_exist')
|
||||
end
|
||||
end
|
||||
|
||||
context 'disabled endpoint' do
|
||||
let(:api_keys_params) do
|
||||
{
|
||||
uid: UIDGenerator.generate(Barong::App.config.uid_prefix),
|
||||
kid: api_key.kid
|
||||
}
|
||||
end
|
||||
|
||||
it 'should raise an error' do
|
||||
do_request
|
||||
expect(response.status).to eq(422)
|
||||
expect_body.to eq(error: 'disabled_management_endpoint')
|
||||
end
|
||||
end
|
||||
|
||||
context 'unexisting uid' do
|
||||
|
||||
let(:api_keys_params) do
|
||||
{
|
||||
uid: 'random',
|
||||
kid: api_key.kid
|
||||
}
|
||||
end
|
||||
|
||||
it 'should raise an error' do
|
||||
do_request
|
||||
expect(response.status).to eq(422)
|
||||
expect_body.to eq(error: 'uid_prefix_doesnt_exist')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
101
spec/api/v2/management/documents_spec.rb
Normal file
101
spec/api/v2/management/documents_spec.rb
Normal file
@@ -0,0 +1,101 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe API::V2::Management::Documents, type: :request do
|
||||
before do
|
||||
defaults_for_management_api_v2_security_configuration!
|
||||
management_api_v2_security_configuration.merge! \
|
||||
scopes: {
|
||||
write_documents: { permitted_signers: %i[alex jeff], mandatory_signers: %i[alex] },
|
||||
}
|
||||
end
|
||||
|
||||
let!(:create_admin_permission) do
|
||||
create :permission,
|
||||
role: 'admin'
|
||||
end
|
||||
let!(:create_member_permission) do
|
||||
create :permission,
|
||||
role: 'member'
|
||||
end
|
||||
let!(:user) { create(:user, :with_profile) }
|
||||
|
||||
describe 'Show user info' do
|
||||
let(:data) do
|
||||
{
|
||||
scope: :write_documents
|
||||
}
|
||||
end
|
||||
let!(:image) { fixture_file_upload('/files/documents_test.jpg', 'image/jpg') }
|
||||
let(:signers) { %i[alex jeff] }
|
||||
let(:params) do
|
||||
{
|
||||
doc_type: 'Passport',
|
||||
doc_expire: '3020-01-22',
|
||||
doc_number: 'AA1234BB',
|
||||
upload: [
|
||||
image
|
||||
]
|
||||
}
|
||||
end
|
||||
let!(:optional_params) do
|
||||
{
|
||||
metadata: {
|
||||
country: Faker::Address.country
|
||||
}
|
||||
}
|
||||
end
|
||||
let(:do_request) do
|
||||
post_json '/api/v2/management/documents',
|
||||
multisig_jwt_management_api_v2({ data: data }, *signers)
|
||||
end
|
||||
|
||||
let(:params) do {
|
||||
uid: user.uid,
|
||||
doc_type: 'Passport',
|
||||
filename: 'documents_test',
|
||||
file_ext: '.jpg',
|
||||
doc_expire: '3020-01-22',
|
||||
doc_number: 'AA1234BB',
|
||||
upload: Base64.strict_encode64(File.open('spec/fixtures/files/documents_test.jpg').read)
|
||||
}
|
||||
end
|
||||
|
||||
it 'push documents to user' do
|
||||
post_json '/api/v2/management/documents', multisig_jwt_management_api_v2({ data: params }, *signers)
|
||||
|
||||
expect(response.status).to eq 201
|
||||
expect(user.documents.length).to eq(1)
|
||||
end
|
||||
|
||||
it 'push documents to user twice' do
|
||||
post_json '/api/v2/management/documents', multisig_jwt_management_api_v2({ data: params }, *signers)
|
||||
|
||||
expect(response.status).to eq 201
|
||||
expect(user.documents.length).to eq(1)
|
||||
|
||||
post_json '/api/v2/management/documents', multisig_jwt_management_api_v2({ data: params }, *signers)
|
||||
expect(response.status).to eq 201
|
||||
expect(user.documents.length).to eq(1)
|
||||
end
|
||||
|
||||
context 'with empty doc_expire' do
|
||||
it 'required doc expire' do
|
||||
allow(Barong::App.config).to receive(:required_docs_expire).and_return(true)
|
||||
expect {
|
||||
post_json '/api/v2/management/documents', multisig_jwt_management_api_v2({ data: params.merge(doc_expire: nil) }, *signers)
|
||||
}.not_to change { Document.count }
|
||||
expect(response.status).to eq 422
|
||||
end
|
||||
|
||||
it 'optional doc expire' do
|
||||
allow(Barong::App.config).to receive(:required_docs_expire).and_return(false)
|
||||
expect {
|
||||
post_json '/api/v2/management/documents', multisig_jwt_management_api_v2({ data: params.merge(doc_expire: nil) }, *signers)
|
||||
}.to change { Document.count }.by 1
|
||||
expect(response.status).to eq 201
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
115
spec/api/v2/management/jwt_authentication_middleware_spec.rb
Normal file
115
spec/api/v2/management/jwt_authentication_middleware_spec.rb
Normal file
@@ -0,0 +1,115 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe API::V2::Management::JWTAuthenticationMiddleware, type: :request do
|
||||
let(:member) { create(:member, :verified_identity) }
|
||||
let(:config) { management_api_v2_security_configuration }
|
||||
|
||||
before do
|
||||
defaults_for_management_api_v2_security_configuration!
|
||||
config.merge! \
|
||||
scopes: {
|
||||
tools: { permitted_signers: %i[alex jeff], mandatory_signers: %i[alex] }
|
||||
}
|
||||
end
|
||||
|
||||
it 'works in standard conditions' do
|
||||
post_json '/api/v2/management/timestamp', multisig_jwt_management_api_v2({}, :alex)
|
||||
expect(response).to be_successful
|
||||
end
|
||||
# FIXME fix swagger_doc
|
||||
# it 'allows GET and doesn\'t require authentication for documentation' do
|
||||
# get '/api/v2/management/swagger_doc'
|
||||
# expect(response).to be_successful
|
||||
# end
|
||||
|
||||
it 'doesn\'t allow query parameters' do
|
||||
post '/api/v2/management/timestamp?foo=baz&baz=qux'
|
||||
expect(response).to have_http_status(400)
|
||||
expect(response.body).to match(/query parameters/i)
|
||||
end
|
||||
|
||||
it 'requires JSON in the request body' do
|
||||
post '/api/v2/management/timestamp', params: 'foo=baz&baz=qux'
|
||||
expect(response).to have_http_status(400)
|
||||
expect(response.body).to match(/only json/i)
|
||||
end
|
||||
|
||||
it 'denies access when not enough signatures are supplied' do
|
||||
post_json '/api/v2/management/timestamp', multisig_jwt_management_api_v2({})
|
||||
expect(response).to have_http_status(401)
|
||||
expect(response.body).to match(/not enough signatures/i)
|
||||
end
|
||||
|
||||
it 'denies access when token is expired' do
|
||||
config[:jwt][:verify_expiration] = true
|
||||
post_json '/api/v2/management/timestamp', multisig_jwt_management_api_v2({ exp: 1.minute.ago.to_i }, :alex)
|
||||
expect(response).to have_http_status(401)
|
||||
expect(response.body).to match(/failed to verify jwt/i)
|
||||
end
|
||||
|
||||
context 'valid issuer' do
|
||||
before { config[:jwt][:verify_iss] = true }
|
||||
before { config[:jwt].merge!(iss: 'qux') }
|
||||
it 'validates issuer' do
|
||||
post_json '/api/v2/management/timestamp', multisig_jwt_management_api_v2({ iss: 'qux' }, :alex)
|
||||
expect(response).to be_successful
|
||||
end
|
||||
end
|
||||
|
||||
context 'invalid issuer' do
|
||||
before { config[:jwt][:verify_iss] = true }
|
||||
before { config[:jwt].merge!(iss: 'qux') }
|
||||
it 'validates issuer' do
|
||||
post_json '/api/v2/management/timestamp', multisig_jwt_management_api_v2({ iss: 'hacker' }, :alex)
|
||||
expect(response).to have_http_status(401)
|
||||
expect(response.body).to match(/failed to verify jwt/i)
|
||||
end
|
||||
end
|
||||
|
||||
context 'valid audience' do
|
||||
before { config[:jwt][:verify_aud] = true }
|
||||
before { config[:jwt].merge!(aud: 'qux') }
|
||||
it 'validates audience' do
|
||||
post_json '/api/v2/management/timestamp', multisig_jwt_management_api_v2({ aud: 'qux' }, :alex)
|
||||
expect(response).to be_successful
|
||||
end
|
||||
end
|
||||
|
||||
context 'invalid audience' do
|
||||
before { config[:jwt][:verify_aud] = true }
|
||||
before { config[:jwt].merge!(aud: 'qux') }
|
||||
it 'validates audience' do
|
||||
post_json '/api/v2/management/timestamp', multisig_jwt_management_api_v2({ aud: 'hacker' }, :alex)
|
||||
expect(response).to have_http_status(401)
|
||||
expect(response.body).to match(/failed to verify jwt/i)
|
||||
end
|
||||
end
|
||||
|
||||
context 'missing JWT ID' do
|
||||
before { config[:jwt][:verify_jti] = true }
|
||||
it 'requires JTI' do
|
||||
post_json '/api/v2/management/timestamp', multisig_jwt_management_api_v2({}, :alex)
|
||||
expect(response).to have_http_status(401)
|
||||
expect(response.body).to match(/failed to verify jwt/i)
|
||||
end
|
||||
end
|
||||
|
||||
context 'issued at in future' do
|
||||
before { config[:jwt][:verify_iat] = true }
|
||||
it 'denies access' do
|
||||
post_json '/api/v2/management/timestamp', multisig_jwt_management_api_v2({ iat: 200.seconds.from_now.to_i }, :alex)
|
||||
expect(response).to have_http_status(401)
|
||||
expect(response.body).to match(/failed to verify jwt/i)
|
||||
end
|
||||
end
|
||||
|
||||
context 'issued at before future' do
|
||||
before { config[:jwt][:verify_iat] = true }
|
||||
it 'allows access' do
|
||||
post_json '/api/v2/management/timestamp', multisig_jwt_management_api_v2({ iat: 3.seconds.ago.to_i }, :alex)
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
end
|
||||
304
spec/api/v2/management/labels_spec.rb
Normal file
304
spec/api/v2/management/labels_spec.rb
Normal file
@@ -0,0 +1,304 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
require 'pry'
|
||||
|
||||
describe API::V2::Management::Labels, type: :request do
|
||||
before do
|
||||
defaults_for_management_api_v2_security_configuration!
|
||||
management_api_v2_security_configuration.merge! \
|
||||
scopes: {
|
||||
write_labels: { permitted_signers: %i[alex jeff], mandatory_signers: %i[alex] },
|
||||
read_labels: { permitted_signers: %i[alex jeff], mandatory_signers: %i[alex] },
|
||||
read_users: { permitted_signers: %i[alex jeff], mandatory_signers: %i[alex] }
|
||||
}
|
||||
end
|
||||
let!(:create_admin_permission) do
|
||||
create :permission,
|
||||
role: 'admin'
|
||||
end
|
||||
let!(:create_member_permission) do
|
||||
create :permission,
|
||||
role: 'member'
|
||||
end
|
||||
let!(:user) { create(:user) }
|
||||
let!(:user_with_private_label) { create(:user) }
|
||||
let!(:user_with_public_label) { create(:user) }
|
||||
|
||||
describe '#filter/users' do
|
||||
let!(:private_label) do
|
||||
create(:label, scope: 'private', key: 'profile', value: 'pending', user: user_with_private_label)
|
||||
end
|
||||
let!(:public_label) do
|
||||
create(:label, scope: 'public', key: 'profile', value: 'pending', user: user_with_public_label)
|
||||
end
|
||||
let(:data) { { key: 'profile', value: 'pending', scope: 'private' } }
|
||||
let(:signers) { %i[alex] }
|
||||
let(:do_request) do
|
||||
post_json '/api/v2/management/labels/filter/users',
|
||||
multisig_jwt_management_api_v2({ data: data }, *signers)
|
||||
end
|
||||
|
||||
it 'filters users based on label attributes. doesnt mix PUBLIC and PRIVATE labels' do
|
||||
# filtering params key: 'profile', value: 'pending', scope: 'private'
|
||||
do_request
|
||||
expect(json_body.count == 1)
|
||||
expect(json_body.first[:email]).to eq(user_with_private_label.attributes.symbolize_keys[:email])
|
||||
expect(json_body.first[:uid]).to eq(user_with_private_label.attributes.symbolize_keys[:uid])
|
||||
end
|
||||
|
||||
it 'filters users based on label timestamp attributes' do
|
||||
# filtering params key: 'profile', to: 1.day.ago
|
||||
data.clear
|
||||
data[:to] = 1.day.ago.to_i
|
||||
data[:key] = 'profile'
|
||||
public_label.update(created_at: 3.days.ago)
|
||||
do_request
|
||||
|
||||
expect(json_body.count == 1)
|
||||
expect(json_body.first[:email]).to eq(user_with_public_label.attributes.symbolize_keys[:email])
|
||||
expect(json_body.first[:uid]).to eq(user_with_public_label.attributes.symbolize_keys[:uid])
|
||||
end
|
||||
|
||||
it 'returns empty array if no mathes found' do
|
||||
# filtering params key: 'documents', value: 'pending', scope: 'private'
|
||||
data[:key] = 'documents'
|
||||
do_request
|
||||
|
||||
expect(json_body.count == 0)
|
||||
expect(json_body).to eq([])
|
||||
end
|
||||
|
||||
it 'returns user with profile if extended is true' do
|
||||
data[:extended] = true
|
||||
do_request
|
||||
|
||||
expect(json_body.first).to include(:profiles)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#list' do
|
||||
let!(:private_label) do
|
||||
create(:label, scope: 'private', user: user)
|
||||
end
|
||||
let!(:public_label) do
|
||||
create(:label, scope: 'public', user: user)
|
||||
end
|
||||
let(:data) do
|
||||
{
|
||||
user_uid: user.uid
|
||||
}
|
||||
end
|
||||
let(:signers) { %i[alex] }
|
||||
|
||||
let(:do_request) do
|
||||
post_json '/api/v2/management/labels/list',
|
||||
multisig_jwt_management_api_v2({ data: data }, *signers)
|
||||
end
|
||||
|
||||
it 'get list of user labels' do
|
||||
do_request
|
||||
expect(response.status).to eq 201
|
||||
expect(json_body.size).to eq 2
|
||||
end
|
||||
end
|
||||
|
||||
describe 'create label' do
|
||||
let(:data) do
|
||||
{
|
||||
user_uid: user.uid,
|
||||
key: 'email',
|
||||
value: 'verified',
|
||||
scope: 'private'
|
||||
}
|
||||
end
|
||||
let(:expected_attributes) do
|
||||
{
|
||||
'key' => 'email',
|
||||
'value' => 'verified',
|
||||
'user_id' => user.id,
|
||||
'scope' => 'private'
|
||||
}
|
||||
end
|
||||
let(:signers) { %i[alex jeff] }
|
||||
|
||||
let(:do_request) do
|
||||
post_json '/api/v2/management/labels',
|
||||
multisig_jwt_management_api_v2({ data: data }, *signers)
|
||||
end
|
||||
|
||||
it 'creates a label' do
|
||||
expect { do_request }.to change { Label.count }.from(0).to(1)
|
||||
expect(response.status).to eq 201
|
||||
expect(Label.first.attributes).to include(expected_attributes)
|
||||
end
|
||||
|
||||
it 'denies access unless enough signatures are supplied' do
|
||||
signers.clear.concat %i[james jeff]
|
||||
expect { do_request }.to_not change { Label.count }
|
||||
expect(response.status).to eq 401
|
||||
end
|
||||
|
||||
it 'denies when user is not found' do
|
||||
data[:user_uid] = 'invalid'
|
||||
expect { do_request }.to_not change { Label.count }
|
||||
expect(response.status).to eq 404
|
||||
end
|
||||
|
||||
context 'when data is blank' do
|
||||
let(:data) { {} }
|
||||
|
||||
it 'renders errors' do
|
||||
do_request
|
||||
expect(response.status).to eq 422
|
||||
expect_body.to eq(error: 'user_uid is missing, user_uid is empty, key is missing, key is empty, value is missing, value is empty')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'update label' do
|
||||
let!(:label) do
|
||||
create(:label, key: 'email', value: 'verified', scope: 'private', description: 'initial label', user: user)
|
||||
end
|
||||
|
||||
let(:data) do
|
||||
{
|
||||
user_uid: user.uid,
|
||||
key: 'email',
|
||||
value: 'rejected',
|
||||
description: 'management api label update test'
|
||||
}
|
||||
end
|
||||
let(:signers) { %i[alex jeff] }
|
||||
|
||||
let(:do_request) do
|
||||
put_json '/api/v2/management/labels',
|
||||
multisig_jwt_management_api_v2({ data: data }, *signers)
|
||||
end
|
||||
|
||||
it 'updates a label value' do
|
||||
expect { do_request }.to change { label.reload.value }.from('verified').to('rejected')
|
||||
expect(response.status).to eq 200
|
||||
end
|
||||
|
||||
|
||||
it 'updates a label value' do
|
||||
expect { do_request }.to change { label.reload.description }.from('initial label').to('management api label update test')
|
||||
expect(response.status).to eq 200
|
||||
end
|
||||
|
||||
it 'denies access unless enough signatures are supplied' do
|
||||
signers.clear.concat %i[james jeff]
|
||||
expect { do_request }.to_not change { label.reload.value }
|
||||
expect(response.status).to eq 401
|
||||
end
|
||||
|
||||
it 'denies when user is not found' do
|
||||
data[:user_uid] = 'invalid'
|
||||
expect { do_request }.to_not change { label.reload.value }
|
||||
expect(response.status).to eq 404
|
||||
end
|
||||
|
||||
context 'when data is blank' do
|
||||
let(:data) { {} }
|
||||
|
||||
it 'renders errors' do
|
||||
do_request
|
||||
expect(response.status).to eq 422
|
||||
expect_body.to eq(error: 'user_uid is missing, user_uid is empty, key is missing, key is empty, value is missing, value is empty')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when label doesnt exist yet with default replace policy' do
|
||||
let(:data) do
|
||||
{
|
||||
user_uid: user.uid,
|
||||
key: 'phone',
|
||||
value: 'verified'
|
||||
}
|
||||
end
|
||||
|
||||
it 'creates a label' do
|
||||
expect(user.labels.find_by(key: 'phone')).to eq(nil)
|
||||
|
||||
do_request
|
||||
expect(response.status).to eq 200
|
||||
expect(user.labels.find_by(key: 'phone')).not_to eq(nil)
|
||||
end
|
||||
|
||||
context 'when data is incomplete' do
|
||||
let(:data) do
|
||||
{
|
||||
user_uid: user.uid,
|
||||
key: 'phone'
|
||||
}
|
||||
end
|
||||
|
||||
it 'receive an error' do
|
||||
expect(user.labels.find_by(key: 'phone')).to eq(nil)
|
||||
|
||||
do_request
|
||||
expect(response.status).to eq 422
|
||||
expect(response.body).to eq "{\"error\":\"value is missing, value is empty\"}"
|
||||
expect(user.labels.find_by(key: 'phone')).to eq(nil)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when label doesnt exist yet with false replace policy' do
|
||||
let(:data) do
|
||||
{
|
||||
user_uid: user.uid,
|
||||
key: 'phone',
|
||||
value: 'verified',
|
||||
replace: false
|
||||
}
|
||||
end
|
||||
|
||||
it 'receives an error' do
|
||||
expect(user.labels.find_by(key: 'phone')).to eq(nil)
|
||||
|
||||
do_request
|
||||
expect(response.status).to eq 404
|
||||
expect(user.labels.find_by(key: 'phone')).to eq(nil)
|
||||
expect(response.body).to eq "{\"error\":\"label doesnt exist\"}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'delete label' do
|
||||
let!(:label) do
|
||||
create(:label, key: 'email', value: 'verified', scope: 'private', user: user)
|
||||
end
|
||||
|
||||
let(:data) do
|
||||
{
|
||||
user_uid: user.uid,
|
||||
key: 'email'
|
||||
}
|
||||
end
|
||||
let(:signers) { %i[alex jeff] }
|
||||
|
||||
let(:do_request) do
|
||||
post_json '/api/v2/management/labels/delete',
|
||||
multisig_jwt_management_api_v2({ data: data }, *signers)
|
||||
end
|
||||
|
||||
it 'deletes a label' do
|
||||
expect { do_request }.to change { Label.count }.from(1).to(0)
|
||||
expect(response.status).to eq 204
|
||||
end
|
||||
|
||||
it 'denies access unless enough signatures are supplied' do
|
||||
signers.clear.concat %i[james jeff]
|
||||
expect { do_request }.to_not change { label.reload.value }
|
||||
expect(response.status).to eq 401
|
||||
end
|
||||
|
||||
it 'denies when user is not found' do
|
||||
data[:user_uid] = 'invalid'
|
||||
expect { do_request }.to_not change { label.reload.value }
|
||||
expect(response.status).to eq 404
|
||||
end
|
||||
end
|
||||
end
|
||||
96
spec/api/v2/management/otp_spec.rb
Normal file
96
spec/api/v2/management/otp_spec.rb
Normal file
@@ -0,0 +1,96 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
require 'pry'
|
||||
|
||||
describe API::V2::Management::Otp, type: :request do
|
||||
before do
|
||||
defaults_for_management_api_v2_security_configuration!
|
||||
management_api_v2_security_configuration.merge! \
|
||||
scopes: {
|
||||
otp_sign: { permitted_signers: %i[alex jeff], mandatory_signers: %i[alex] }
|
||||
}
|
||||
end
|
||||
let!(:create_admin_permission) do
|
||||
create :permission,
|
||||
role: 'admin'
|
||||
end
|
||||
let!(:create_member_permission) do
|
||||
create :permission,
|
||||
role: 'member'
|
||||
end
|
||||
let!(:user) { create(:user, otp: otp_enabled) }
|
||||
|
||||
describe 'POST /otp/sign' do
|
||||
let(:data) do
|
||||
{
|
||||
user_uid: user.uid,
|
||||
otp_code: valid_otp_code,
|
||||
jwt: jwt
|
||||
}
|
||||
end
|
||||
let(:signers) { %i[alex jeff] }
|
||||
let(:valid_otp_code) { '1111' }
|
||||
let(:invalid_otp_code) { '1234' }
|
||||
let(:jwt) { applogic_signed_jwt(amount: '1 BTC') }
|
||||
let(:otp_enabled) { true }
|
||||
let(:do_request) do
|
||||
post_json '/api/v2/management/otp/sign',
|
||||
multisig_jwt_management_api_v2({ data: data }, *signers)
|
||||
end
|
||||
let(:valid_payload_keys) do
|
||||
%i[payload signatures]
|
||||
end
|
||||
|
||||
before do
|
||||
allow(TOTPService).to receive(:validate?)
|
||||
.with(user.uid, valid_otp_code) { true }
|
||||
allow(TOTPService).to receive(:validate?)
|
||||
.with(user.uid, invalid_otp_code) { false }
|
||||
end
|
||||
|
||||
it 'signs a request' do
|
||||
do_request
|
||||
expect(json_body.keys).to eq(valid_payload_keys)
|
||||
expect(response.status).to eq 201
|
||||
end
|
||||
|
||||
it 'renders an error when jwt is not a Hash' do
|
||||
data[:jwt] = 'invalid'
|
||||
do_request
|
||||
expect_body.to eq(error: 'jwt is invalid')
|
||||
expect(response.status).to eq 422
|
||||
end
|
||||
|
||||
it 'renders an error when jwt is not RFC' do
|
||||
data[:jwt] = { data: 'invalid' }
|
||||
do_request
|
||||
expect(json_body[:error]).to include('JWT is invalid by the reason')
|
||||
expect(response.status).to eq 422
|
||||
end
|
||||
|
||||
it 'renders an error when otp code is invalid' do
|
||||
data[:otp_code] = invalid_otp_code
|
||||
do_request
|
||||
expect_body.to eq(error: 'OTP code is invalid')
|
||||
expect(response.status).to eq 422
|
||||
end
|
||||
|
||||
it 'renders an error when account is not found' do
|
||||
data[:user_uid] = 'invalid'
|
||||
do_request
|
||||
expect_body.to eq error: 'Record is not found'
|
||||
expect(response.status).to eq 404
|
||||
end
|
||||
|
||||
context 'when data is blank' do
|
||||
let(:data) { {} }
|
||||
|
||||
it 'renders errors' do
|
||||
do_request
|
||||
expect_body.to eq(error: "user_uid is missing, user_uid is empty, otp_code is missing, otp_code is empty, jwt is missing, jwt is empty")
|
||||
expect(response.status).to eq 422
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
319
spec/api/v2/management/phones_spec.rb
Normal file
319
spec/api/v2/management/phones_spec.rb
Normal file
@@ -0,0 +1,319 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
describe API::V2::Management::Phones, type: :request do
|
||||
before do
|
||||
defaults_for_management_api_v2_security_configuration!
|
||||
management_api_v2_security_configuration.merge! \
|
||||
scopes: {
|
||||
write_phones: { permitted_signers: %i[alex jeff], mandatory_signers: %i[alex] },
|
||||
read_phones: { permitted_signers: %i[alex jeff], mandatory_signers: %i[alex] },
|
||||
}
|
||||
end
|
||||
let!(:create_admin_permission) do
|
||||
create :permission,
|
||||
role: 'admin'
|
||||
end
|
||||
let!(:create_member_permission) do
|
||||
create :permission,
|
||||
role: 'member'
|
||||
end
|
||||
let!(:user) { create(:user) }
|
||||
|
||||
describe 'POST /phones/get' do
|
||||
let(:signers) { %i[alex jeff] }
|
||||
let(:data) { params.merge(scope: :read_phones) }
|
||||
|
||||
let(:do_request) do
|
||||
post_json '/api/v2/management/phones/get',
|
||||
multisig_jwt_management_api_v2({ data: data }, *signers)
|
||||
end
|
||||
|
||||
let(:params) do
|
||||
phone_params
|
||||
end
|
||||
|
||||
context 'valid request' do
|
||||
context 'user without phones' do
|
||||
let(:phone_params) do
|
||||
{
|
||||
uid: user.uid
|
||||
}
|
||||
end
|
||||
|
||||
it 'get list of phones' do
|
||||
do_request
|
||||
expect_status_to_eq 201
|
||||
expect_body.to eq []
|
||||
end
|
||||
end
|
||||
|
||||
context 'user with phones' do
|
||||
let!(:phone) { create(:phone, user: user) }
|
||||
let(:phone_params) do
|
||||
{
|
||||
uid: user.uid
|
||||
}
|
||||
end
|
||||
|
||||
it 'get list of phones' do
|
||||
do_request
|
||||
expect_status_to_eq 201
|
||||
expect(json_body.count).to eq 1
|
||||
expect(json_body.first[:number]).to eq phone.number
|
||||
expect(json_body.first[:country]).to eq phone.country
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'invalid request' do
|
||||
let(:phone_params) do
|
||||
{
|
||||
uid: 'invalid_uid'
|
||||
}
|
||||
end
|
||||
|
||||
it 'renders an error' do
|
||||
do_request
|
||||
expect_body.to eq(error: 'user.doesnt_exist')
|
||||
expect_status.to eq 422
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'POST /phones' do
|
||||
let(:signers) { %i[alex jeff] }
|
||||
let(:data) { params.merge(scope: :write_phones) }
|
||||
|
||||
let(:do_request) do
|
||||
post_json '/api/v2/management/phones',
|
||||
multisig_jwt_management_api_v2({ data: data }, *signers)
|
||||
end
|
||||
|
||||
let(:params) do
|
||||
phone_params
|
||||
end
|
||||
|
||||
context 'valid request' do
|
||||
let(:phone_params) do
|
||||
{
|
||||
uid: user.uid,
|
||||
number: '12345678911'
|
||||
}
|
||||
end
|
||||
|
||||
it 'creates a phone' do
|
||||
expect { do_request }.to change { Phone.count }.by(1)
|
||||
expect_status_to_eq 201
|
||||
|
||||
result = JSON.parse(response.body)
|
||||
expect(result['country']).to eq 'US'
|
||||
expect(result['number']).to eq phone_params[:number]
|
||||
end
|
||||
end
|
||||
|
||||
context 'invalid request' do
|
||||
context 'when phone is invalid' do
|
||||
let(:phone_params) do
|
||||
{
|
||||
uid: user.uid,
|
||||
number: '123'
|
||||
}
|
||||
end
|
||||
|
||||
it 'renders an error' do
|
||||
do_request
|
||||
expect_body.to eq(error: 'management.phone.invalid_num')
|
||||
expect_status.to eq 400
|
||||
end
|
||||
end
|
||||
|
||||
context 'when phone is missing' do
|
||||
let(:phone_params) do
|
||||
{
|
||||
uid: user.uid
|
||||
}
|
||||
end
|
||||
|
||||
it 'renders an error' do
|
||||
do_request
|
||||
expect_status.to eq 422
|
||||
expect_body.to eq(error: 'number is missing, number is empty')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when phone is already exists' do
|
||||
let!(:phone) do
|
||||
create(:phone, validated_at: validated_at)
|
||||
end
|
||||
|
||||
let(:phone_params) do
|
||||
{
|
||||
uid: user.uid,
|
||||
number: phone.number
|
||||
}
|
||||
end
|
||||
|
||||
context 'when phone verified' do
|
||||
let(:validated_at) { 1.minutes.ago }
|
||||
|
||||
it 'renders an error' do
|
||||
do_request
|
||||
expect_body.to eq(error: 'management.phone.number_exist')
|
||||
expect_status.to eq 400
|
||||
end
|
||||
end
|
||||
|
||||
context 'when phone verified but number is not sanitized' do
|
||||
let(:validated_at) { 1.minutes.ago }
|
||||
let(:phone_params) do
|
||||
{
|
||||
uid: user.uid,
|
||||
number: '++#{phone.number}'
|
||||
}
|
||||
end
|
||||
|
||||
it 'renders an error' do
|
||||
do_request
|
||||
expect_body.to eq(error: 'management.phone.invalid_num')
|
||||
expect_status.to eq 400
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when phone exists on international format' do
|
||||
let(:phone_params) do
|
||||
{
|
||||
uid: user.uid,
|
||||
number: '+44 07418084106'
|
||||
}
|
||||
end
|
||||
let(:international_phone) { '447418084106' }
|
||||
let!(:phone) do
|
||||
create(:phone, validated_at: 1.minute.ago, number: international_phone)
|
||||
end
|
||||
|
||||
it 'renders an error' do
|
||||
do_request
|
||||
expect_body.to eq(error: 'management.phone.number_exist')
|
||||
expect_status.to eq 400
|
||||
end
|
||||
end
|
||||
|
||||
context 'when phone exists for current user' do
|
||||
let!(:phone) { create(:phone, number: '447418084106', user_id: user.id)}
|
||||
let(:phone_params) do
|
||||
{
|
||||
uid: user.uid,
|
||||
number: '447418084106'
|
||||
}
|
||||
end
|
||||
|
||||
it 'renders an error' do
|
||||
do_request
|
||||
expect_body.to eq(error: 'management.phone.exists')
|
||||
expect_status.to eq 400
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'POST /phone/delete' do
|
||||
let(:signers) { %i[alex jeff] }
|
||||
let(:data) { params.merge(scope: :write_phones) }
|
||||
|
||||
let(:do_request) do
|
||||
post_json '/api/v2/management/phones/delete',
|
||||
multisig_jwt_management_api_v2({ data: data }, *signers)
|
||||
end
|
||||
|
||||
let(:params) do
|
||||
phone_params
|
||||
end
|
||||
|
||||
context 'valid request' do
|
||||
context 'user with one phone number' do
|
||||
let!(:phone) { create(:phone, number: '447418084106', user_id: user.id)}
|
||||
|
||||
let(:phone_params) do
|
||||
{
|
||||
uid: user.uid,
|
||||
number: phone.number
|
||||
}
|
||||
end
|
||||
|
||||
it 'show deleted phone' do
|
||||
expect { do_request }.to change { Phone.count }.by(-1)
|
||||
expect_status.to eq 201
|
||||
expect(json_body[:number]).to eq phone.number
|
||||
expect(json_body[:country]).to eq phone.country
|
||||
end
|
||||
end
|
||||
|
||||
context 'user with several phone numbers' do
|
||||
let!(:phone1) { create(:phone, number: '447418084106', user_id: user.id)}
|
||||
let!(:phone2) { create(:phone, number: '447418084107', user_id: user.id)}
|
||||
|
||||
let(:phone_params) do
|
||||
{
|
||||
uid: user.uid,
|
||||
number: phone2.number
|
||||
}
|
||||
end
|
||||
|
||||
it 'show deleted phone' do
|
||||
expect { do_request }.to change { Phone.count }.by(-1)
|
||||
expect_status.to eq 201
|
||||
expect(json_body[:number]).to eq phone2.number
|
||||
expect(json_body[:country]).to eq phone2.country
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'invalid request' do
|
||||
context 'invalid user' do
|
||||
let(:phone_params) do
|
||||
{
|
||||
uid: 'invalid_uid',
|
||||
number: 'number'
|
||||
}
|
||||
end
|
||||
|
||||
it 'renders an error' do
|
||||
do_request
|
||||
expect_body.to eq(error: 'user.doesnt_exist')
|
||||
expect_status.to eq 422
|
||||
end
|
||||
end
|
||||
|
||||
context 'invalid phone number' do
|
||||
let(:phone_params) do
|
||||
{
|
||||
uid: user.uid,
|
||||
number: 'invalid_number'
|
||||
}
|
||||
end
|
||||
|
||||
it 'renders an error' do
|
||||
do_request
|
||||
expect_body.to eq(error: 'management.phone.doesnt_exists')
|
||||
expect_status.to eq 422
|
||||
end
|
||||
end
|
||||
|
||||
context 'non existed phone number' do
|
||||
let(:phone_params) do
|
||||
{
|
||||
uid: user.uid,
|
||||
number: '1111111111'
|
||||
}
|
||||
end
|
||||
|
||||
it 'renders an error' do
|
||||
do_request
|
||||
expect_body.to eq(error: 'management.phone.doesnt_exists')
|
||||
expect_status.to eq 422
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
134
spec/api/v2/management/profiles_spec.rb
Normal file
134
spec/api/v2/management/profiles_spec.rb
Normal file
@@ -0,0 +1,134 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe API::V2::Management::Profiles, type: :request do
|
||||
before do
|
||||
defaults_for_management_api_v2_security_configuration!
|
||||
management_api_v2_security_configuration.merge! \
|
||||
scopes: {
|
||||
read_users: { permitted_signers: %i[alex jeff], mandatory_signers: %i[alex] },
|
||||
write_users: { permitted_signers: %i[alex jeff], mandatory_signers: %i[alex] }
|
||||
}
|
||||
end
|
||||
|
||||
let!(:create_admin_permission) do
|
||||
create :permission,
|
||||
role: 'admin'
|
||||
end
|
||||
let!(:create_member_permission) do
|
||||
create :permission,
|
||||
role: 'member'
|
||||
end
|
||||
|
||||
let(:signers) { %i[alex jeff] }
|
||||
let(:data) { params.merge(scope: :write_users) }
|
||||
|
||||
let(:do_request) do
|
||||
post_json '/api/v2/management/profiles',
|
||||
multisig_jwt_management_api_v2({ data: data }, *signers)
|
||||
end
|
||||
|
||||
context 'when profile params are provided' do
|
||||
let(:params) do
|
||||
profile_params
|
||||
end
|
||||
|
||||
context 'when params are valid' do
|
||||
let(:user) { create :user }
|
||||
let(:profile_params) do
|
||||
{
|
||||
uid: user.uid,
|
||||
first_name: Faker::Name.first_name,
|
||||
last_name: Faker::Name.last_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
|
||||
|
||||
it 'creates a profile' do
|
||||
expect { do_request }.to change { Profile.count }.by(1)
|
||||
expect_status_to_eq 201
|
||||
|
||||
result = JSON.parse(response.body)
|
||||
expect(result['profiles'][0]['state']).to eq 'drafted'
|
||||
expect(result['profiles'][0]['last_name']).to eq profile_params[:last_name]
|
||||
expect(result['profiles'][0]['dob']).to eq profile_params[:dob].to_s
|
||||
end
|
||||
end
|
||||
|
||||
context 'when postcode is not provided' do
|
||||
let(:user) { create :user }
|
||||
let(:profile_params) do
|
||||
{
|
||||
uid: user.uid,
|
||||
first_name: Faker::Name.first_name,
|
||||
last_name: Faker::Name.last_name,
|
||||
dob: Faker::Date.birthday,
|
||||
country: Faker::Address.country_code_long,
|
||||
city: Faker::Address.city,
|
||||
address: Faker::Address.state
|
||||
}
|
||||
end
|
||||
|
||||
it 'create a profile' do
|
||||
expect { do_request }.to change { Profile.count }
|
||||
expect_status_to_eq 201
|
||||
result = JSON.parse(response.body)
|
||||
expect(result['profiles'][0]['state']).to eq 'drafted'
|
||||
expect(result['profiles'][0]['last_name']).to eq profile_params[:last_name]
|
||||
expect(result['profiles'][0]['dob']).to eq profile_params[:dob].to_s
|
||||
end
|
||||
end
|
||||
|
||||
context 'when profile state is provided' do
|
||||
let(:user) { create :user }
|
||||
let(:profile_params) do
|
||||
{
|
||||
uid: user.uid,
|
||||
first_name: Faker::Name.first_name,
|
||||
last_name: Faker::Name.last_name,
|
||||
dob: Faker::Date.birthday,
|
||||
country: Faker::Address.country_code_long,
|
||||
city: Faker::Address.city,
|
||||
address: Faker::Address.state,
|
||||
state: 'rejected'
|
||||
}
|
||||
end
|
||||
|
||||
it 'create a profile' do
|
||||
expect { do_request }.to change { Profile.count }
|
||||
expect_status_to_eq 201
|
||||
result = JSON.parse(response.body)
|
||||
expect(result['profiles'][0]['state']).to eq 'rejected'
|
||||
expect(result['profiles'][0]['last_name']).to eq profile_params[:last_name]
|
||||
expect(result['profiles'][0]['dob']).to eq profile_params[:dob].to_s
|
||||
end
|
||||
end
|
||||
|
||||
context 'when params are invalid' do
|
||||
let(:user) { create :user }
|
||||
let(:profile_params) do
|
||||
{
|
||||
uid: user.uid,
|
||||
first_name: Faker::Name.first_name,
|
||||
last_name: Faker::Name.last_name,
|
||||
dob: Faker::Date.birthday,
|
||||
country: 'a',
|
||||
city: Faker::Address.city,
|
||||
address: Faker::Address.state,
|
||||
postcode: Faker::Address.zip_code
|
||||
}
|
||||
end
|
||||
|
||||
it 'renders an error' do
|
||||
expect { do_request }.to_not change { Profile.count }
|
||||
expect_status_to_eq 422
|
||||
expect(json_body[:error]).to eq ['Country must have alpha2 or alpha3 format']
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
373
spec/api/v2/management/service_accounts_spec.rb
Normal file
373
spec/api/v2/management/service_accounts_spec.rb
Normal file
@@ -0,0 +1,373 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
require 'pry'
|
||||
|
||||
describe API::V2::Management::ServiceAccounts, type: :request do
|
||||
before do
|
||||
defaults_for_management_api_v2_security_configuration!
|
||||
management_api_v2_security_configuration.merge! \
|
||||
scopes: {
|
||||
read_service_accounts: { permitted_signers: %i[alex jeff], mandatory_signers: %i[alex] },
|
||||
write_service_accounts: { permitted_signers: %i[alex jeff], mandatory_signers: %i[alex] }
|
||||
}
|
||||
end
|
||||
let!(:create_member_permission) do
|
||||
create :permission,
|
||||
role: 'member'
|
||||
end
|
||||
let!(:create_service_account_permission) do
|
||||
create :permission,
|
||||
role: 'service_account'
|
||||
end
|
||||
let!(:create_admin_permission) do
|
||||
create :permission,
|
||||
role: 'admin'
|
||||
end
|
||||
|
||||
let!(:user) { create(:user, role: 'member') }
|
||||
let!(:service_account) { create(:service_account, user: user) }
|
||||
|
||||
describe 'Show service_account info' do
|
||||
let(:data) do
|
||||
{
|
||||
scope: :read_service_accounts
|
||||
}
|
||||
end
|
||||
|
||||
let(:expected_attributes) do
|
||||
%i[email uid role level state user created_at updated_at]
|
||||
end
|
||||
let(:signers) { %i[alex jeff] }
|
||||
|
||||
let(:do_request) do
|
||||
post_json '/api/v2/management/service_accounts/get',
|
||||
multisig_jwt_management_api_v2({ data: data }, *signers)
|
||||
end
|
||||
|
||||
it 'reads service_account info by uid' do
|
||||
data[:uid] = service_account.uid
|
||||
do_request
|
||||
|
||||
expect(response.status).to eq 200
|
||||
expect(json_body.keys).to eq expected_attributes
|
||||
end
|
||||
|
||||
it 'reads service_account info by email' do
|
||||
data[:email] = service_account.email
|
||||
do_request
|
||||
|
||||
expect(response.status).to eq 200
|
||||
expect(json_body.keys).to eq expected_attributes
|
||||
end
|
||||
|
||||
it 'denies when uid is not found' do
|
||||
data[:uid] = 'invalid'
|
||||
do_request
|
||||
expect(response.status).to eq 404
|
||||
end
|
||||
|
||||
it 'denies when email is not found' do
|
||||
data[:email] = 'invalid'
|
||||
do_request
|
||||
expect(response.status).to eq 404
|
||||
end
|
||||
end
|
||||
|
||||
describe 'Returns array of service accounts as collection' do
|
||||
let(:data) do
|
||||
{
|
||||
scope: :read_service_accounts
|
||||
}
|
||||
end
|
||||
let(:signers) { %i[alex jeff] }
|
||||
|
||||
let(:do_request) do
|
||||
post_json '/api/v2/management/service_accounts/list',
|
||||
multisig_jwt_management_api_v2({ data: data }, *signers)
|
||||
end
|
||||
|
||||
context 'service_accounts' do
|
||||
let!(:test_service_account) { create(:service_account, email: 'testa@gmail.com', user: user) }
|
||||
let!(:second_service_account) { create(:service_account, email: 'testb@gmail.com', user: user) }
|
||||
let!(:third_service_account) { create(:service_account, email: 'testd@gmail.com', user: user) }
|
||||
let!(:fourth_service_account) { create(:service_account, email: 'testc@gmail.com', user: user) }
|
||||
|
||||
include_context 'bearer authentication'
|
||||
|
||||
let(:do_service_accounts_request) do
|
||||
post_json '/api/v2/management/service_accounts/get',
|
||||
multisig_jwt_management_api_v2({ data: data }), headers: auth_header
|
||||
end
|
||||
it 'denies access for user JWT instead of management signature' do
|
||||
do_service_accounts_request
|
||||
expect(response.status).to eq 401
|
||||
end
|
||||
|
||||
it 'denies access unless enough signatures are supplied' do
|
||||
signers.clear.concat %i[james jeff]
|
||||
do_request
|
||||
expect(response.status).to eq 401
|
||||
end
|
||||
|
||||
it 'returns list of service_accounts' do
|
||||
do_request
|
||||
|
||||
service_accounts = JSON.parse(response.body)
|
||||
expect(ServiceAccount.count).to eq service_accounts.count
|
||||
end
|
||||
|
||||
context 'pagination test' do
|
||||
let(:service_account_list_params) do
|
||||
{
|
||||
scope: :read_users,
|
||||
limit: 2
|
||||
}
|
||||
end
|
||||
|
||||
it 'returns 1st page as default, limit 2 users per page' do
|
||||
service_account_list_params[:page] = 1
|
||||
post_json '/api/v2/management/service_accounts/list', multisig_jwt_management_api_v2({ data: service_account_list_params }, *signers), headers: auth_header
|
||||
|
||||
expect(response.headers.fetch('Total')).to eq ServiceAccount.all.count.to_s
|
||||
expect(response.headers.fetch('Page')).to eq '1'
|
||||
expect(response.headers.fetch('Per-Page')).to eq '2'
|
||||
end
|
||||
|
||||
it 'returns 2nd page, limit 2 users per page' do
|
||||
service_account_list_params[:page] = 2
|
||||
post_json '/api/v2/management/service_accounts/list', multisig_jwt_management_api_v2({ data: service_account_list_params }, *signers), headers: auth_header
|
||||
|
||||
expect(response.headers.fetch('Total')).to eq ServiceAccount.all.count.to_s
|
||||
expect(response.headers.fetch('Page')).to eq '2'
|
||||
expect(response.headers.fetch('Per-Page')).to eq '2'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'Create a service account' do
|
||||
let(:signers) { %i[alex jeff] }
|
||||
let(:data) { params.merge(scope: :write_service_accounts) }
|
||||
|
||||
let(:do_request) do
|
||||
post_json '/api/v2/management/service_accounts/create',
|
||||
multisig_jwt_management_api_v2({ data: data }, *signers)
|
||||
end
|
||||
|
||||
context 'when uid is present' do
|
||||
context 'when email is valid' do
|
||||
let(:params) do
|
||||
{
|
||||
service_account_email: 'valid_email@example.com',
|
||||
service_account_uid: 'Fai5aesoLEcx',
|
||||
service_account_role: 'admin',
|
||||
owner_uid: user.uid
|
||||
}
|
||||
end
|
||||
|
||||
it 'creates a service account' do
|
||||
expect { do_request }.to change { ServiceAccount.count }.by(1)
|
||||
expect_status_to_eq 201
|
||||
end
|
||||
end
|
||||
|
||||
context 'when params are blank' do
|
||||
let(:params) { {} }
|
||||
|
||||
it 'renders an error' do
|
||||
do_request
|
||||
expect_status_to_eq 422
|
||||
expect_body.to eq(error: 'service_account_role is missing, service_account_role is empty')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when email is bad' do
|
||||
let(:params) { { service_account_email: 'bad_email', service_account_uid: 'Fai5aesoLEcx', service_account_role: 'member', owner_uid: user.uid } }
|
||||
|
||||
it 'renders an error' do
|
||||
expect { do_request }.to_not change { ServiceAccount.count }
|
||||
expect_status_to_eq 422
|
||||
expect_body.to eq(error: ['Email is invalid'])
|
||||
end
|
||||
end
|
||||
|
||||
context 'when role does not exist' do
|
||||
let(:params) { { service_account_email: 'valid_email@example.com', service_account_uid: 'Fai5aesoLEcx', service_account_role: 'invalid', owner_uid: user.uid } }
|
||||
|
||||
it 'renders an error' do
|
||||
expect { do_request }.to_not change { ServiceAccount.count }
|
||||
expect_status_to_eq 422
|
||||
expect_body.to eq(error: ['Role doesnt_exist'])
|
||||
end
|
||||
end
|
||||
|
||||
context 'when uid is not uniq, the same as user one' do
|
||||
let(:params) { { service_account_email: 'valid_email@example.com', service_account_uid: user.uid, service_account_role: 'member', owner_uid: user.uid } }
|
||||
|
||||
it 'renders an error' do
|
||||
expect { do_request }.to_not change { ServiceAccount.count }
|
||||
expect_status_to_eq 422
|
||||
expect(json_body[:error].first).to include 'Email or uid not_uniq'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'Update a service account' do
|
||||
let(:signers) { %i[alex jeff] }
|
||||
let(:data) { params.merge(scope: :write_service_accounts) }
|
||||
let!(:service_account) { create(:service_account, :without_user) }
|
||||
|
||||
let(:do_request) do
|
||||
post_json '/api/v2/management/service_accounts/update',
|
||||
multisig_jwt_management_api_v2({ data: data }, *signers)
|
||||
end
|
||||
|
||||
context 'when params are blank' do
|
||||
let(:params) { {} }
|
||||
|
||||
it 'renders an error' do
|
||||
do_request
|
||||
expect_status_to_eq 422
|
||||
expect_body.to eq(error: 'uid is missing, uid is empty')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when service account doesnt exists' do
|
||||
let(:params) do
|
||||
{
|
||||
uid: 'example'
|
||||
}
|
||||
end
|
||||
|
||||
it 'renders an error' do
|
||||
do_request
|
||||
expect_status_to_eq 422
|
||||
expect_body.to eq(error: 'Service account doesnt exist')
|
||||
end
|
||||
end
|
||||
|
||||
context 'update service account' do
|
||||
context do
|
||||
let(:params) do
|
||||
{
|
||||
uid: service_account.uid
|
||||
}
|
||||
end
|
||||
|
||||
context 'service account without user' do
|
||||
it 'shouldnt modify service account' do
|
||||
do_request
|
||||
expect_status_to_eq 201
|
||||
|
||||
res = JSON.parse(response.body)
|
||||
expect(res['state']).to eq 'pending'
|
||||
expect(res['level']).to eq 0
|
||||
expect(res['user']).to eq nil
|
||||
end
|
||||
end
|
||||
|
||||
context 'service account with user' do
|
||||
let!(:service_account) { create(:service_account) }
|
||||
|
||||
it 'shouldnt modify service account' do
|
||||
owner = service_account.user
|
||||
do_request
|
||||
expect_status_to_eq 201
|
||||
|
||||
res = JSON.parse(response.body)
|
||||
expect(res['state']).to eq owner.state
|
||||
expect(res['level']).to eq owner.level
|
||||
expect(res['user']['uid']).to eq owner.uid
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context do
|
||||
context 'service account without user' do
|
||||
let!(:user_with_phone) { create(:user, :with_phone) }
|
||||
let(:params) do
|
||||
{
|
||||
uid: service_account.uid,
|
||||
owner_uid: user_with_phone.uid
|
||||
}
|
||||
end
|
||||
|
||||
it 'should modify service account' do
|
||||
expect(service_account.level).to eq 0
|
||||
expect(service_account.state).to eq 'pending'
|
||||
expect(service_account.user).to eq nil
|
||||
|
||||
do_request
|
||||
expect_status_to_eq 201
|
||||
|
||||
res = JSON.parse(response.body)
|
||||
expect(res['user']['uid']).to eq user_with_phone.uid
|
||||
expect(res['level']).to eq user_with_phone.level
|
||||
expect(res['state']).to eq user_with_phone.state
|
||||
end
|
||||
end
|
||||
|
||||
context 'service account with user' do
|
||||
let!(:user_with_phone) { create(:user, :with_phone) }
|
||||
let!(:user_with_profile) { create(:user, :with_profile) }
|
||||
let!(:service_account) { create(:service_account, user: user_with_phone)}
|
||||
|
||||
let(:params) do
|
||||
{
|
||||
uid: service_account.uid,
|
||||
owner_uid: user_with_profile.uid
|
||||
}
|
||||
end
|
||||
|
||||
it 'should modify service account' do
|
||||
expect(service_account.level).to eq user_with_phone.level
|
||||
expect(service_account.state).to eq user_with_phone.state
|
||||
expect(service_account.user.uid).to eq user_with_phone.uid
|
||||
|
||||
do_request
|
||||
expect_status_to_eq 201
|
||||
|
||||
res = JSON.parse(response.body)
|
||||
expect(res['user']['uid']).to eq user_with_profile.uid
|
||||
expect(res['level']).to eq user_with_profile.level
|
||||
expect(res['state']).to eq user_with_profile.state
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'Delete a service account' do
|
||||
let(:signers) { %i[alex jeff] }
|
||||
let(:data) { params.merge(scope: :write_service_accounts) }
|
||||
|
||||
let(:do_request) do
|
||||
post_json '/api/v2/management/service_accounts/delete',
|
||||
multisig_jwt_management_api_v2({ data: data }, *signers)
|
||||
end
|
||||
|
||||
context do
|
||||
let(:params) { { uid: service_account.uid } }
|
||||
|
||||
it do
|
||||
do_request
|
||||
expect_status_to_eq 200
|
||||
|
||||
service_account = JSON.parse(response.body)
|
||||
expect(service_account['state']).to eq 'disabled'
|
||||
end
|
||||
end
|
||||
|
||||
context 'when params are blank' do
|
||||
let(:params) { {} }
|
||||
|
||||
it 'renders an error' do
|
||||
do_request
|
||||
expect_status_to_eq 422
|
||||
expect_body.to eq(error: 'uid is missing, uid is empty')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
556
spec/api/v2/management/users_spec.rb
Normal file
556
spec/api/v2/management/users_spec.rb
Normal file
@@ -0,0 +1,556 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
require 'pry'
|
||||
|
||||
describe API::V2::Management::Users, type: :request do
|
||||
before do
|
||||
defaults_for_management_api_v2_security_configuration!
|
||||
management_api_v2_security_configuration.merge! \
|
||||
scopes: {
|
||||
read_users: { permitted_signers: %i[alex jeff], mandatory_signers: %i[alex] },
|
||||
write_users: { permitted_signers: %i[alex jeff], mandatory_signers: %i[alex] }
|
||||
}
|
||||
end
|
||||
let!(:create_admin_permission) do
|
||||
create :permission,
|
||||
role: 'admin'
|
||||
end
|
||||
let!(:create_member_permission) do
|
||||
create :permission,
|
||||
role: 'member'
|
||||
end
|
||||
let!(:user) { create(:user, :with_profile) }
|
||||
|
||||
describe 'Show user info' do
|
||||
let(:data) do
|
||||
{
|
||||
scope: :read_users
|
||||
}
|
||||
end
|
||||
let(:expected_attributes) do
|
||||
%i[email uid role level otp state data profiles referral_uid created_at updated_at]
|
||||
end
|
||||
let(:extended_attributes) do
|
||||
%i[email uid role level otp state data profiles labels phones documents data_storages comments referral_uid created_at updated_at]
|
||||
end
|
||||
let(:signers) { %i[alex jeff] }
|
||||
|
||||
let(:do_request) do
|
||||
post_json '/api/v2/management/users/get',
|
||||
multisig_jwt_management_api_v2({ data: data }, *signers)
|
||||
end
|
||||
|
||||
it 'reads extended user info by uid' do
|
||||
data[:uid] = user.uid
|
||||
do_request
|
||||
|
||||
expect(response.status).to eq 201
|
||||
expect(json_body.keys).to match_array extended_attributes
|
||||
expect(json_body).to include(:profiles, :comments, :phones, :documents)
|
||||
expect(json_body[:profiles][0][:last_name]).to eq user.profiles[0].last_name
|
||||
expect(json_body[:profiles][0][:dob]).to eq user.profiles[0].dob.to_s
|
||||
end
|
||||
|
||||
it 'reads full user info by email' do
|
||||
data[:email] = user.email
|
||||
|
||||
do_request
|
||||
expect(response.status).to eq 201
|
||||
expect(json_body.keys).to match_array extended_attributes
|
||||
expect(json_body).to include(:profiles, :comments, :phones, :documents)
|
||||
expect(json_body[:profiles][0][:last_name]).to eq user.profiles[0].last_name
|
||||
expect(json_body[:profiles][0][:dob]).to eq user.profiles[0].dob.to_s
|
||||
end
|
||||
|
||||
let!(:phone) do
|
||||
create(:phone, validated_at: 1.minutes.ago, user_id: user.id)
|
||||
end
|
||||
|
||||
it 'reads full user info by user phone' do
|
||||
data[:phone_num] = phone.number
|
||||
|
||||
do_request
|
||||
expect(response.status).to eq 201
|
||||
expect(json_body.keys).to match_array extended_attributes
|
||||
expect(json_body).to include(:profiles, :comments, :phones, :documents)
|
||||
expect(json_body[:profiles][0][:last_name]).to eq user.profiles[0].last_name
|
||||
expect(json_body[:profiles][0][:dob]).to eq user.profiles[0].dob.to_s
|
||||
end
|
||||
|
||||
it 'allows only one of phone, uid, email' do
|
||||
data[:phone_num] = phone.number
|
||||
data[:email] = user.email
|
||||
data[:uid] = user.uid
|
||||
do_request
|
||||
expect(response.status).to eq 422
|
||||
expect_body.to eq(error: 'uid, email, phone_num are mutually exclusive')
|
||||
end
|
||||
|
||||
it 'denies access unless enough signatures are supplied' do
|
||||
signers.clear.concat %i[james jeff]
|
||||
do_request
|
||||
expect(response.status).to eq 401
|
||||
end
|
||||
|
||||
it 'denies when uid is not found' do
|
||||
data[:uid] = 'invalid'
|
||||
do_request
|
||||
expect(response.status).to eq 404
|
||||
end
|
||||
|
||||
it 'denies when email is not found' do
|
||||
data[:email] = 'invalid'
|
||||
do_request
|
||||
expect(response.status).to eq 404
|
||||
end
|
||||
|
||||
it 'denies when email is not found' do
|
||||
data[:phone_num] = 'invalid'
|
||||
do_request
|
||||
expect(response.status).to eq 404
|
||||
end
|
||||
|
||||
context 'when data is blank' do
|
||||
let(:data) { {} }
|
||||
|
||||
it 'renders errors' do
|
||||
do_request
|
||||
expect(response.status).to eq 422
|
||||
expect_body.to eq(error: 'uid, email, phone_num are missing, exactly one parameter must be provided')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'Returns array of users as collection' do
|
||||
let(:data) do
|
||||
{
|
||||
scope: :read_users
|
||||
}
|
||||
end
|
||||
let(:signers) { %i[alex jeff] }
|
||||
|
||||
let(:do_request) do
|
||||
post_json '/api/v2/management/users/list',
|
||||
multisig_jwt_management_api_v2({ data: data }, *signers)
|
||||
end
|
||||
|
||||
context 'users' do
|
||||
let!(:test_user) { create(:user, email: 'testa@gmail.com', role: 'admin') }
|
||||
let!(:second_user) { create(:user, email: 'testb@gmail.com') }
|
||||
let!(:third_user) { create(:user, email: 'testd@gmail.com') }
|
||||
let!(:fourth_user) { create(:user, email: 'testc@gmail.com') }
|
||||
|
||||
def validate_fields(user)
|
||||
user.attributes.slice('email', 'role', 'level', 'otp', 'state', 'uid', 'data')
|
||||
end
|
||||
|
||||
include_context 'bearer authentication'
|
||||
|
||||
let(:do_user_request) do
|
||||
post_json '/api/v2/management/users/get',
|
||||
multisig_jwt_management_api_v2({ data: data }), headers: auth_header
|
||||
end
|
||||
it 'denies access for user JWT instead of management signature' do
|
||||
do_user_request
|
||||
expect(response.status).to eq 401
|
||||
end
|
||||
|
||||
it 'denies access unless enough signatures are supplied' do
|
||||
signers.clear.concat %i[james jeff]
|
||||
do_request
|
||||
expect(response.status).to eq 401
|
||||
end
|
||||
|
||||
it 'returns list of users' do
|
||||
do_request
|
||||
|
||||
users = JSON.parse(response.body)
|
||||
expect(User.count).to eq users.count
|
||||
expect(validate_fields(User.first)).to eq users.first.except('referral_uid')
|
||||
expect(validate_fields(User.second)).to eq users.second.except('referral_uid')
|
||||
expect(validate_fields(User.third)).to eq users.third.except('referral_uid')
|
||||
expect(validate_fields(User.last)).to eq users.last.except('referral_uid')
|
||||
end
|
||||
|
||||
context 'pagination test' do
|
||||
let(:users_list_params) do
|
||||
{
|
||||
scope: :read_users,
|
||||
limit: 2
|
||||
}
|
||||
end
|
||||
|
||||
it 'returns 1st page as default, limit 2 users per page' do
|
||||
users_list_params[:page] = 1
|
||||
post_json '/api/v2/management/users/list', multisig_jwt_management_api_v2({ data: users_list_params }, *signers), headers: auth_header
|
||||
|
||||
expect(response.headers.fetch('Total')).to eq User.all.count.to_s
|
||||
expect(response.headers.fetch('Page')).to eq '1'
|
||||
expect(response.headers.fetch('Per-Page')).to eq '2'
|
||||
end
|
||||
|
||||
it 'returns 2nd page, limit 2 users per page' do
|
||||
users_list_params[:page] = 2
|
||||
post_json '/api/v2/management/users/list', multisig_jwt_management_api_v2({ data: users_list_params }, *signers), headers: auth_header
|
||||
|
||||
expect(response.headers.fetch('Total')).to eq User.all.count.to_s
|
||||
expect(response.headers.fetch('Page')).to eq '2'
|
||||
expect(response.headers.fetch('Per-Page')).to eq '2'
|
||||
end
|
||||
end
|
||||
|
||||
context 'filtering test' do
|
||||
let(:users_list_params) do
|
||||
{
|
||||
scope: :read_users
|
||||
}
|
||||
end
|
||||
|
||||
it 'returns filtered list of users when only one filter param given created_at and from' do
|
||||
users_list_params[:range] = 'created'
|
||||
User.first.update(created_at: 5.hours.ago)
|
||||
users_list_params[:from] = 8.hours.ago.to_i
|
||||
users_list_params[:to] = 2.hours.ago.to_i
|
||||
|
||||
post_json '/api/v2/management/users/list', multisig_jwt_management_api_v2({ data: users_list_params }, *signers), headers: auth_header
|
||||
|
||||
expect(response.status).to eq 200
|
||||
expect(json_body.count).to eq (1)
|
||||
end
|
||||
|
||||
it 'returns filtered list of users when only one filter param given updated_at' do
|
||||
users_list_params[:range] = 'updated'
|
||||
User.first.update(updated_at: 5.hours.ago)
|
||||
users_list_params[:from] = 8.hours.ago.to_i
|
||||
users_list_params[:to] = 2.hours.ago.to_i
|
||||
|
||||
post_json '/api/v2/management/users/list', multisig_jwt_management_api_v2({ data: users_list_params }, *signers), headers: auth_header
|
||||
|
||||
expect(response.status).to eq 200
|
||||
expect(json_body.count).to eq (1)
|
||||
expect(json_body[0]).not_to include(:profiles)
|
||||
end
|
||||
|
||||
it 'returns filetered list of users with extended param' do
|
||||
users_list_params[:extended] = true
|
||||
post_json '/api/v2/management/users/list', multisig_jwt_management_api_v2({ data: users_list_params }, *signers), headers: auth_header
|
||||
expect(response.status).to eq 200
|
||||
expect(json_body[0]).to include(:profiles)
|
||||
expect(json_body.first[:profiles][0][:last_name]).to eq user.profiles[0].last_name
|
||||
expect(json_body.first[:profiles][0][:dob]).to eq user.profiles[0].dob.to_s
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'Update role and data of existing user' do
|
||||
let(:signers) { %i[alex jeff] }
|
||||
let(:data) { params.merge(scope: :write_users) }
|
||||
|
||||
let(:do_request) do
|
||||
post_json '/api/v2/management/users/update',
|
||||
multisig_jwt_management_api_v2({ data: data }, *signers)
|
||||
end
|
||||
|
||||
context 'when data is present' do
|
||||
let!(:user) { create :user, :with_profile }
|
||||
let(:params) do
|
||||
{
|
||||
uid: user.uid,
|
||||
data: { nationality: 'us' }.to_json
|
||||
}
|
||||
end
|
||||
it 'updates data field' do
|
||||
do_request
|
||||
|
||||
expect_status_to_eq 201
|
||||
expect(json_body).to include(:profiles)
|
||||
expect(json_body[:profiles][0][:last_name]).to eq user.profiles[0].last_name
|
||||
expect(json_body[:profiles][0][:dob]).to eq user.profiles[0].dob.to_s
|
||||
expect(user.reload.data).to eq({ nationality: 'us' }.to_json)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when role is present' do
|
||||
let(:user) { create :user }
|
||||
let(:params) do
|
||||
{
|
||||
uid: user.uid,
|
||||
role: 'admin'
|
||||
}
|
||||
end
|
||||
it 'updates role field' do
|
||||
do_request
|
||||
|
||||
expect_status_to_eq 201
|
||||
expect(user.reload.role).to eq('admin')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when data and role are present' do
|
||||
let(:user) { create :user }
|
||||
let(:params) do
|
||||
{
|
||||
uid: user.uid,
|
||||
data: { nationality: 'us' }.to_json,
|
||||
role: 'admin'
|
||||
}
|
||||
end
|
||||
it 'updates data and role fields' do
|
||||
do_request
|
||||
|
||||
expect_status_to_eq 201
|
||||
expect(user.reload.data).to eq({ nationality: 'us' }.to_json)
|
||||
expect(user.reload.role).to eq('admin')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when none of parameters are present' do
|
||||
let(:user) { create :user }
|
||||
let(:params) do
|
||||
{
|
||||
uid: user.uid,
|
||||
}
|
||||
end
|
||||
it 'renders error' do
|
||||
do_request
|
||||
|
||||
expect_status_to_eq 422
|
||||
expect_body.to eq(error: "role, data are missing, at least one parameter must be provided")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'Create an user' do
|
||||
let(:signers) { %i[alex jeff] }
|
||||
let(:data) { params.merge(scope: :write_users) }
|
||||
|
||||
let(:do_request) do
|
||||
post_json '/api/v2/management/users',
|
||||
multisig_jwt_management_api_v2({ data: data }, *signers)
|
||||
end
|
||||
|
||||
context 'when password is present' do
|
||||
context 'when email and password are valid' do
|
||||
let(:params) do
|
||||
{
|
||||
email: 'valid_email@example.com',
|
||||
password: 'Fai5aesoLEcx'
|
||||
}
|
||||
end
|
||||
it 'creates an user' do
|
||||
expect { do_request }.to change { User.count }.by(1)
|
||||
expect_status_to_eq 201
|
||||
end
|
||||
end
|
||||
|
||||
context 'when params are blank' do
|
||||
let(:params) { {} }
|
||||
|
||||
it 'renders an error' do
|
||||
do_request
|
||||
expect_status_to_eq 422
|
||||
expect_body.to eq(error: 'email is missing, email is empty, password is missing, password is empty')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when email is bad' do
|
||||
let(:params) { { email: 'bad_email', password: 'Password1' } }
|
||||
|
||||
it 'renders an error' do
|
||||
expect { do_request }.to_not change { User.count }
|
||||
expect_status_to_eq 422
|
||||
expect_body.to eq(error: ['Email is invalid','Password weak'])
|
||||
end
|
||||
end
|
||||
|
||||
context 'creates an account with referral uid' do
|
||||
let(:params) { { email: 'test@test.com', password: 'Fai5aesoLEcx', referral_uid: User.last.uid } }
|
||||
|
||||
it 'renders an error' do
|
||||
expect { do_request }.to change { User.count }.by(1)
|
||||
expect_status_to_eq 201
|
||||
expect(json_body).to include(:email, :uid, :role, :level,
|
||||
:state, :otp, :profiles)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when password is bad' do
|
||||
let(:params) { { email: 'valid_email@example.com', password: 'password' } }
|
||||
|
||||
it 'renders an error' do
|
||||
expect { do_request }.to_not change { User.count }
|
||||
expect_status_to_eq 422
|
||||
expect(json_body[:error].first).to include 'Password requirements'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'Imports an existing user' do
|
||||
let(:signers) { %i[alex jeff] }
|
||||
let(:data) { params.merge(scope: :write_users) }
|
||||
|
||||
let(:do_request) do
|
||||
post_json '/api/v2/management/users/import',
|
||||
multisig_jwt_management_api_v2({ data: data }, *signers)
|
||||
end
|
||||
|
||||
let!(:email) { 'valid_email@example.com' }
|
||||
let!(:password) { 'Fai5aesoLEcx' }
|
||||
let!(:password_digest) do
|
||||
User.new(password: password).send(:password_digest)
|
||||
end
|
||||
let(:params) do
|
||||
{ email: email, password_digest: password_digest }
|
||||
end
|
||||
|
||||
context 'when email and password_hash are valid' do
|
||||
it 'creates an user and signs in with credentials' do
|
||||
expect { do_request }.to change { User.count }.by(1)
|
||||
expect_status_to_eq 201
|
||||
expect(json_body).to include(:email, :uid, :role, :level,
|
||||
:state, :otp, :profiles)
|
||||
|
||||
# TODO: Check if imported user is able to login
|
||||
end
|
||||
end
|
||||
|
||||
context 'when params are blank' do
|
||||
let(:params) { {} }
|
||||
|
||||
it 'renders an error' do
|
||||
do_request
|
||||
expect_status_to_eq 422
|
||||
expect_body.to eq(error: 'email is missing, email is empty, password_digest is missing, password_digest is empty')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when phone is provided' do
|
||||
let(:params) do
|
||||
{
|
||||
email: email,
|
||||
password_digest: password_digest,
|
||||
phone: phone
|
||||
}
|
||||
end
|
||||
|
||||
context 'when phone is valid' do
|
||||
let(:phone) { build(:phone).number }
|
||||
|
||||
it 'creates a phone' do
|
||||
expect { do_request }.to change { Phone.count }.by(1)
|
||||
expect_status_to_eq 201
|
||||
end
|
||||
end
|
||||
|
||||
context 'when phone is invalid' do
|
||||
let(:phone) { '12345' }
|
||||
|
||||
it 'renders an error' do
|
||||
expect { do_request }.to_not change { Phone.count }
|
||||
expect_status_to_eq 422
|
||||
expect(json_body[:error]).to eq ['Number is invalid']
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when profile params are provided' do
|
||||
let(:params) do
|
||||
{
|
||||
email: email,
|
||||
password_digest: password_digest
|
||||
}.merge(profile_params)
|
||||
end
|
||||
|
||||
context 'when params are valid' do
|
||||
let(:profile_params) do
|
||||
{
|
||||
first_name: Faker::Name.first_name,
|
||||
last_name: Faker::Name.last_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
|
||||
|
||||
it 'creates a profile' do
|
||||
expect { do_request }.to change { Profile.count }.by(1)
|
||||
result = JSON.parse(response.body)
|
||||
expect(result['profiles'][0]['last_name']).to eq profile_params[:last_name]
|
||||
expect(result['profiles'][0]['dob']).to eq profile_params[:dob].to_s
|
||||
expect(result['profiles'][0]['state']).to eq 'drafted'
|
||||
expect_status_to_eq 201
|
||||
end
|
||||
end
|
||||
|
||||
context 'when postcode is not provided' do
|
||||
let(:profile_params) do
|
||||
{
|
||||
first_name: Faker::Name.first_name,
|
||||
last_name: Faker::Name.last_name,
|
||||
dob: Faker::Date.birthday,
|
||||
country: Faker::Address.country_code_long,
|
||||
city: Faker::Address.city,
|
||||
address: Faker::Address.state
|
||||
}
|
||||
end
|
||||
|
||||
it 'create a profile' do
|
||||
expect { do_request }.to change { Profile.count }
|
||||
result = JSON.parse(response.body)
|
||||
expect(result['profiles'][0]['last_name']).to eq profile_params[:last_name]
|
||||
expect(result['profiles'][0]['dob']).to eq profile_params[:dob].to_s
|
||||
expect(result['profiles'][0]['state']).to eq 'drafted'
|
||||
expect_status_to_eq 201
|
||||
end
|
||||
end
|
||||
|
||||
context 'when profile state is provided' do
|
||||
let(:profile_params) do
|
||||
{
|
||||
first_name: Faker::Name.first_name,
|
||||
last_name: Faker::Name.last_name,
|
||||
dob: Faker::Date.birthday,
|
||||
country: Faker::Address.country_code_long,
|
||||
city: Faker::Address.city,
|
||||
address: Faker::Address.state,
|
||||
state: 'rejected'
|
||||
}
|
||||
end
|
||||
|
||||
it 'create a profile' do
|
||||
expect { do_request }.to change { Profile.count }
|
||||
result = JSON.parse(response.body)
|
||||
expect(result['profiles'][0]['last_name']).to eq profile_params[:last_name]
|
||||
expect(result['profiles'][0]['dob']).to eq profile_params[:dob].to_s
|
||||
expect(result['profiles'][0]['state']).to eq 'rejected'
|
||||
expect_status_to_eq 201
|
||||
end
|
||||
end
|
||||
|
||||
context 'when params are invalid' do
|
||||
let(:profile_params) do
|
||||
{
|
||||
first_name: Faker::Name.first_name,
|
||||
last_name: Faker::Name.last_name,
|
||||
dob: Faker::Date.birthday,
|
||||
country: 'a',
|
||||
city: Faker::Address.city,
|
||||
address: Faker::Address.state,
|
||||
postcode: Faker::Address.zip_code
|
||||
}
|
||||
end
|
||||
|
||||
it 'renders an error' do
|
||||
expect { do_request }.to_not change { Profile.count }
|
||||
expect_status_to_eq 422
|
||||
expect(json_body[:error]).to eq ['Country must have alpha2 or alpha3 format']
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user