Merge pull request #119 from rbkmoney/FF-114/ft/wallet_tests

FF-114: wallet tests
This commit is contained in:
Roman Pushkov 2019-09-18 15:02:57 +03:00 committed by GitHub
commit c43872da8c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 261 additions and 148 deletions

1
.gitignore vendored
View File

@ -16,3 +16,4 @@ docker-compose.yml
# wapi
apps/swag_*
tags

View File

@ -1,6 +1,8 @@
-module(ff_wallet_handler_SUITE).
-include_lib("stdlib/include/assert.hrl").
-include_lib("fistful_proto/include/ff_proto_wallet_thrift.hrl").
-include_lib("dmsl/include/dmsl_payment_processing_thrift.hrl").
-export([all/0]).
-export([groups/0]).
@ -11,9 +13,11 @@
-export([init_per_testcase/2]).
-export([end_per_testcase/2]).
-export([create_wallet_ok/1]).
-export([create_wallet_identity_fails/1]).
-export([create_wallet_currency_fails/1]).
-export([create_ok/1]).
-export([create_error_identity_not_found/1]).
-export([create_error_currency_not_found/1]).
-export([create_error_party_blocked/1]).
-export([create_error_party_suspended/1]).
-type config() :: ct_helper:config().
-type test_case_name() :: ct_helper:test_case_name().
@ -30,9 +34,11 @@ all() ->
groups() ->
[
{default, [parallel], [
create_wallet_ok,
create_wallet_identity_fails,
create_wallet_currency_fails
create_ok,
create_error_identity_not_found,
create_error_currency_not_found,
create_error_party_blocked,
create_error_party_suspended
]}
].
@ -74,72 +80,70 @@ init_per_testcase(Name, C) ->
end_per_testcase(_Name, _C) ->
ok = ff_woody_ctx:unset().
-spec create_ok(config()) -> test_return().
-spec create_error_identity_not_found(config()) -> test_return().
-spec create_error_currency_not_found(config()) -> test_return().
-spec create_error_party_blocked(config()) -> test_return().
-spec create_error_party_suspended(config()) -> test_return().
-spec create_wallet_ok(config()) -> test_return().
-spec create_wallet_identity_fails(config()) -> test_return().
-spec create_wallet_currency_fails(config()) -> test_return().
create_ok(C) ->
Party = create_party(C),
Currency = <<"RUB">>,
ID = genlib:unique(),
ExternalID = genlib:unique(),
IdentityID = create_person_identity(Party, C),
Ctx = #{<<"TEST_NS">> => {obj, #{ {str, <<"KEY">>} => {b, true}}}},
Params = construct_wallet_params(ID, IdentityID, Currency, ExternalID, Ctx),
CreateResult = call_service('Create', [Params]),
GetResult = call_service('Get', [ID]),
{ok, Wallet} = GetResult,
Account = Wallet#wlt_Wallet.account,
CurrencyRef = Account#account_Account.currency,
?assertMatch(CreateResult, GetResult),
?assertMatch(<<"Valet">>, Wallet#wlt_Wallet.name),
?assertMatch(unblocked, Wallet#wlt_Wallet.blocking),
?assertMatch(ExternalID, Wallet#wlt_Wallet.external_id),
?assertMatch(Ctx, Wallet#wlt_Wallet.context),
?assertMatch(IdentityID, Account#account_Account.identity),
?assertMatch(Currency, CurrencyRef#'CurrencyRef'.symbolic_code).
create_wallet_ok(C) ->
Party = create_party(C),
Currency = <<"RUB">>,
WalletName = <<"Valet">>,
ID = genlib:unique(),
ExternalId = genlib:unique(),
IdentityID = create_person_identity(Party, C),
Ctx = #{<<"TEST_NS">> => {obj, #{ {str, <<"KEY">>} => {b, true} }}},
Params = #wlt_WalletParams{
id = ID,
name = WalletName,
external_id = ExternalId,
context = Ctx,
account_params = #account_AccountParams{
identity_id = IdentityID,
symbolic_code = Currency
}
},
{ok, Wallet} = call_service('Create', [Params]),
{ok, Wallet2} = call_service('Get', [ID]),
Wallet = Wallet2,
WalletName = Wallet2#wlt_Wallet.name,
unblocked = Wallet2#wlt_Wallet.blocking,
ExternalId = Wallet2#wlt_Wallet.external_id,
Ctx = Wallet2#wlt_Wallet.context,
Account = Wallet2#wlt_Wallet.account,
IdentityID = Account#account_Account.identity,
CurrencyRef = Account#account_Account.currency,
Currency = CurrencyRef#'CurrencyRef'.symbolic_code.
create_wallet_identity_fails(_C) ->
Currency = <<"RUB">>,
ID = genlib:unique(),
ExternalId = genlib:unique(),
create_error_identity_not_found(_C) ->
Currency = <<"RUB">>,
ID = genlib:unique(),
ExternalID = genlib:unique(),
IdentityID = genlib:unique(),
Params = #wlt_WalletParams{
id = ID,
name = <<"Valet">>,
external_id = ExternalId,
account_params = #account_AccountParams{
identity_id = IdentityID,
symbolic_code = Currency
}
},
{exception, {fistful_IdentityNotFound}} = call_service('Create', [Params]).
Params = construct_wallet_params(ID, IdentityID, Currency, ExternalID),
Result = call_service('Create', [Params]),
?assertMatch({exception, #fistful_IdentityNotFound{}}, Result).
create_wallet_currency_fails(C) ->
Party = create_party(C),
Currency = <<"RBK.MONEY">>,
ID = genlib:unique(),
create_error_currency_not_found(C) ->
Party = create_party(C),
Currency = <<"RBK.MONEY">>,
ID = genlib:unique(),
IdentityID = create_person_identity(Party, C),
Params = #wlt_WalletParams{
id = ID,
name = <<"Valet">>,
account_params = #account_AccountParams{
identity_id = IdentityID,
symbolic_code = Currency
}
Params = construct_wallet_params(ID, IdentityID, Currency),
Result = call_service('Create', [Params]),
?assertMatch({exception, #fistful_CurrencyNotFound{}}, Result).
},
{exception, {fistful_CurrencyNotFound}} = call_service('Create', [Params]).
create_error_party_blocked(C) ->
Party = create_party(C),
Currency = <<"RUB">>,
ID = genlib:unique(),
IdentityID = create_person_identity(Party, C),
ok = block_party(Party, C),
Params = construct_wallet_params(ID, IdentityID, Currency),
Result = call_service('Create', [Params]),
?assertMatch({exception, #fistful_PartyInaccessible{}}, Result).
create_error_party_suspended(C) ->
Party = create_party(C),
Currency = <<"RUB">>,
ID = genlib:unique(),
IdentityID = create_person_identity(Party, C),
ok = suspend_party(Party, C),
Params = construct_wallet_params(ID, IdentityID, Currency),
Result = call_service('Create', [Params]),
?assertMatch({exception, #fistful_PartyInaccessible{}}, Result).
%%-----------
%% Internal
@ -169,4 +173,55 @@ create_identity(Party, ProviderID, ClassID, _C) ->
#{party => Party, provider => ProviderID, class => ClassID},
ff_ctx:new()
),
ID.
ID.
construct_userinfo() ->
#payproc_UserInfo{id = <<"fistful">>, type = construct_usertype()}.
construct_usertype() ->
{service_user, #payproc_ServiceUser{}}.
suspend_party(Party, C) ->
Service = {dmsl_payment_processing_thrift, 'PartyManagement'},
Args = [construct_userinfo(), Party],
Request = {Service, 'Suspend', Args},
_ = ff_woody_client:call(partymgmt, Request, ct_helper:get_woody_ctx(C)),
ok.
block_party(Party, C) ->
Service = {dmsl_payment_processing_thrift, 'PartyManagement'},
Args = [construct_userinfo(), Party, <<"BECAUSE">>],
Request = {Service, 'Block', Args},
_ = ff_woody_client:call(partymgmt, Request, ct_helper:get_woody_ctx(C)),
ok.
construct_wallet_params(ID, IdentityID, Currency) ->
#wlt_WalletParams{
id = ID,
name = <<"Valet">>,
account_params = #account_AccountParams{
identity_id = IdentityID,
symbolic_code = Currency
}
}.
construct_wallet_params(ID, IdentityID, Currency, ExternalID) ->
#wlt_WalletParams{
id = ID,
name = <<"Valet">>,
external_id = ExternalID,
account_params = #account_AccountParams{
identity_id = IdentityID,
symbolic_code = Currency
}
}.
construct_wallet_params(ID, IdentityID, Currency, ExternalID, Ctx) ->
#wlt_WalletParams{
id = ID,
name = <<"Valet">>,
external_id = ExternalID,
context = Ctx,
account_params = #account_AccountParams{
identity_id = IdentityID,
symbolic_code = Currency
}
}.

View File

@ -23,9 +23,7 @@
{created, account()}.
-type create_error() ::
{accounter, any()} |
{contract, any()} |
{terms, any()} |
{terms, ff_party:validate_account_creation_error()} |
{party, ff_party:inaccessibility()}.
-export_type([id/0]).
@ -78,13 +76,7 @@ accounter_account_id(#{accounter_account_id := AccounterID}) ->
%% Actuators
-spec create(id(), identity(), currency()) ->
{ok, [event()]} |
{error,
{accounter, any()} |
{contract, any()} |
{terms, any()} |
{party, ff_party:inaccessibility()}
}.
{ok, [event()]} | {error, create_error()}.
create(ID, Identity, Currency) ->
do(fun () ->
@ -96,11 +88,11 @@ create(ID, Identity, Currency) ->
wallet_id => ID,
currency => #domain_CurrencyRef{symbolic_code = CurrencyID}
},
Terms = unwrap(contract, ff_party:get_contract_terms(
{ok, Terms} = ff_party:get_contract_terms(
PartyID, ContractID, TermVarset, ff_time:now()
)),
),
valid = unwrap(terms, ff_party:validate_account_creation(Terms, CurrencyID)),
AccounterID = unwrap(accounter, create_account(ID, Currency)),
{ok, AccounterID} = create_account(ID, Currency),
[{created, #{
id => ID,
identity => ff_identity:id(Identity),

View File

@ -19,6 +19,9 @@
email := binary()
}.
-type validate_account_creation_error() ::
currency_validation_error().
-type validate_deposit_creation_error() ::
currency_validation_error() |
{invalid_terms, _Details} |
@ -41,6 +44,7 @@
-export_type([wallet_id/0]).
-export_type([party_params/0]).
-export_type([validate_deposit_creation_error/0]).
-export_type([validate_account_creation_error/0]).
-export_type([get_contract_terms_error/0]).
-export_type([validate_withdrawal_creation_error/0]).
-export_type([cash/0]).
@ -176,8 +180,7 @@ get_wallet_payment_institution_id(Wallet) ->
-spec get_contract_terms(wallet(), body(), timestamp()) -> Result when
Result :: {ok, terms()} | {error, Error},
Error ::
get_contract_terms_error().
Error :: get_contract_terms_error().
get_contract_terms(Wallet, Body, Timestamp) ->
WalletID = ff_wallet:id(Wallet),
@ -219,14 +222,12 @@ get_contract_terms(PartyID, ContractID, Varset, Timestamp) ->
-spec validate_account_creation(terms(), currency_id()) -> Result when
Result :: {ok, valid} | {error, Error},
Error ::
{invalid_terms, _Details} |
currency_validation_error().
Error :: currency_validation_error().
validate_account_creation(Terms, CurrencyID) ->
#domain_TermSet{wallets = WalletTerms} = Terms,
do(fun () ->
valid = unwrap(validate_wallet_currencies_term_is_reduced(WalletTerms)),
{ok, valid} = validate_wallet_currencies_term_is_reduced(WalletTerms),
valid = unwrap(validate_wallet_terms_currency(CurrencyID, WalletTerms))
end).

View File

@ -63,11 +63,7 @@ ctx(St) ->
}.
-spec create(id(), params(), ctx()) ->
ok |
{error,
ff_wallet:create_error() |
exists
}.
ok | {error, exists | ff_wallet:create_error() }.
create(ID, Params = #{identity := IdentityID, name := Name, currency := CurrencyID}, Ctx) ->
do(fun () ->

View File

@ -6,21 +6,32 @@
-export([init_per_testcase/2]).
-export([end_per_testcase/2]).
-export([get_missing_fails/1]).
-export([create_missing_identity_fails/1]).
-export([create_missing_currency_fails/1]).
-export([create_wallet_ok/1]).
-export([get_error_not_found/1]).
-export([create_ok/1]).
-export([create_error_id_exists/1]).
-export([create_error_identity_not_found/1]).
-export([create_error_currency_not_found/1]).
-export([create_error_party_blocked/1]).
-export([create_error_party_suspended/1]).
-export([create_error_terms_not_allowed_currency/1]).
-spec get_missing_fails(config()) -> test_return().
-spec create_missing_identity_fails(config()) -> test_return().
-spec create_missing_currency_fails(config()) -> test_return().
-spec create_wallet_ok(config()) -> test_return().
-spec get_error_not_found(config()) -> test_return().
-spec create_ok(config()) -> test_return().
-spec create_error_id_exists(config()) -> test_return().
-spec create_error_identity_not_found(config()) -> test_return().
-spec create_error_currency_not_found(config()) -> test_return().
-spec create_error_party_blocked(config()) -> test_return().
-spec create_error_party_suspended(config()) -> test_return().
-spec create_error_terms_not_allowed_currency(config()) -> test_return().
%%
-import(ct_helper, [cfg/2]).
-import(ff_pipeline, [unwrap/1]).
-include_lib("stdlib/include/assert.hrl").
-include_lib("dmsl/include/dmsl_payment_processing_thrift.hrl").
-type config() :: ct_helper:config().
-type test_case_name() :: ct_helper:test_case_name().
-type group_name() :: ct_helper:group_name().
@ -30,10 +41,14 @@
all() ->
[
get_missing_fails,
create_missing_identity_fails,
create_missing_currency_fails,
create_wallet_ok
get_error_not_found,
create_ok,
create_error_id_exists,
create_error_identity_not_found,
create_error_currency_not_found,
create_error_party_blocked,
create_error_party_suspended,
create_error_terms_not_allowed_currency
].
-spec init_per_suite(config()) -> config().
@ -118,54 +133,73 @@ end_per_testcase(_Name, _C) ->
%%
get_missing_fails(_C) ->
{error, notfound} = ff_wallet_machine:get(genlib:unique()).
get_error_not_found(_C) ->
?assertMatch({error, notfound}, ff_wallet_machine:get(genlib:unique())).
create_missing_identity_fails(_C) ->
ID = genlib:unique(),
{error, {identity, notfound}} = ff_wallet_machine:create(
ID,
#{
identity => genlib:unique(),
name => <<"HAHA NO">>,
currency => <<"RUB">>
},
ff_ctx:new()
).
create_ok(C) ->
ID = genlib:unique(),
Party = create_party(C),
IdentityID = create_identity(Party, C),
WalletParams = construct_wallet_params(IdentityID),
CreateResult = ff_wallet_machine:create(ID, WalletParams, ff_ctx:new()),
Wallet = ff_wallet_machine:wallet(unwrap(ff_wallet_machine:get(ID))),
Accessibility = unwrap(ff_wallet:is_accessible(Wallet)),
Account = ff_account:accounter_account_id(ff_wallet:account(Wallet)),
{Amount, <<"RUB">>} = unwrap(ff_transaction:balance(Account)),
CurrentAmount = ff_indef:current(Amount),
?assertMatch(ok, CreateResult),
?assertMatch(accessible, Accessibility),
?assertMatch(0, CurrentAmount).
create_missing_currency_fails(C) ->
ID = genlib:unique(),
Party = create_party(C),
IdentityID = create_identity(Party, C),
{error, {currency, notfound}} = ff_wallet_machine:create(
ID,
#{
identity => IdentityID,
name => <<"HAHA YES">>,
currency => <<"EOS">>
},
ff_ctx:new()
).
create_error_id_exists(C) ->
ID = genlib:unique(),
Party = create_party(C),
IdentityID = create_identity(Party, C),
WalletParams = construct_wallet_params(IdentityID),
CreateResult0 = ff_wallet_machine:create(ID, WalletParams, ff_ctx:new()),
CreateResult1 = ff_wallet_machine:create(ID, WalletParams, ff_ctx:new()),
?assertMatch(ok, CreateResult0),
?assertMatch({error, exists}, CreateResult1).
create_wallet_ok(C) ->
ID = genlib:unique(),
Party = create_party(C),
IdentityID = create_identity(Party, C),
ok = ff_wallet_machine:create(
ID,
#{
identity => IdentityID,
name => <<"HAHA YES">>,
currency => <<"RUB">>
},
ff_ctx:new()
),
Wallet = ff_wallet_machine:wallet(unwrap(ff_wallet_machine:get(ID))),
{ok, accessible} = ff_wallet:is_accessible(Wallet),
Account = ff_account:accounter_account_id(ff_wallet:account(Wallet)),
{ok, {Amount, <<"RUB">>}} = ff_transaction:balance(Account),
0 = ff_indef:current(Amount),
ok.
create_error_identity_not_found(_C) ->
ID = genlib:unique(),
WalletParams = construct_wallet_params(genlib:unique()),
CreateResult = ff_wallet_machine:create(ID, WalletParams, ff_ctx:new()),
?assertMatch({error, {identity, notfound}}, CreateResult).
create_error_currency_not_found(C) ->
ID = genlib:unique(),
Party = create_party(C),
IdentityID = create_identity(Party, C),
WalletParams = construct_wallet_params(IdentityID, <<"EOS">>),
CreateResult = ff_wallet_machine:create(ID, WalletParams, ff_ctx:new()),
?assertMatch({error, {currency, notfound}}, CreateResult).
create_error_party_blocked(C) ->
ID = genlib:unique(),
Party = create_party(C),
IdentityID = create_identity(Party, C),
ok = block_party(Party, C),
WalletParams = construct_wallet_params(IdentityID),
CreateResult = ff_wallet_machine:create(ID, WalletParams, ff_ctx:new()),
?assertMatch({error, {party, {inaccessible, blocked}}}, CreateResult).
create_error_party_suspended(C) ->
ID = genlib:unique(),
Party = create_party(C),
IdentityID = create_identity(Party, C),
ok = suspend_party(Party, C),
WalletParams = construct_wallet_params(IdentityID),
CreateResult = ff_wallet_machine:create(ID, WalletParams, ff_ctx:new()),
?assertMatch({error, {party, {inaccessible, suspended}}}, CreateResult).
create_error_terms_not_allowed_currency(C) ->
ID = genlib:unique(),
Party = create_party(C),
IdentityID = create_identity(Party, C),
WalletParams = construct_wallet_params(IdentityID, <<"USD">>),
CreateResult = ff_wallet_machine:create(ID, WalletParams, ff_ctx:new()),
?assertMatch({error, {terms, {terms_violation, {not_allowed_currency, _}}}}, CreateResult).
%%
@ -238,6 +272,7 @@ get_domain_config(C) ->
ct_domain:proxy(?prx(1), <<"Inspector proxy">>),
ct_domain:contract_template(?tmpl(1), ?trms(1)),
ct_domain:term_set_hierarchy(?trms(1), [ct_domain:timed_term_set(get_default_termset())]),
ct_domain:currency(?cur(<<"RUB">>)),
@ -265,3 +300,36 @@ get_default_termset() ->
]}
}
}.
construct_wallet_params(IdentityID) ->
#{
identity => IdentityID,
name => <<"HAHA YES">>,
currency => <<"RUB">>
}.
construct_wallet_params(IdentityID, Currency) ->
#{
identity => IdentityID,
name => <<"HAHA YES">>,
currency => Currency
}.
construct_userinfo() ->
#payproc_UserInfo{id = <<"fistful">>, type = construct_usertype()}.
construct_usertype() ->
{service_user, #payproc_ServiceUser{}}.
suspend_party(Party, C) ->
Service = {dmsl_payment_processing_thrift, 'PartyManagement'},
Args = [construct_userinfo(), Party],
Request = {Service, 'Suspend', Args},
_ = ff_woody_client:call(partymgmt, Request, ct_helper:get_woody_ctx(C)),
ok.
block_party(Party, C) ->
Service = {dmsl_payment_processing_thrift, 'PartyManagement'},
Args = [construct_userinfo(), Party, <<"BECAUSE">>],
Request = {Service, 'Block', Args},
_ = ff_woody_client:call(partymgmt, Request, ct_helper:get_woody_ctx(C)),
ok.