TD-943: Fixes invoice template state reconstruction and adds tests (#139)

* TD-943: Fixes invoice template state reconstruction and adds tests

* Fixes typo
This commit is contained in:
Aleksey Kashapov 2024-07-22 18:08:54 +03:00 committed by GitHub
parent 1c99fe0733
commit 99a6c45fc0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 152 additions and 16 deletions

View File

@ -146,7 +146,7 @@ validate_price({unlim, _}, _Shop) ->
ok.
start(ID, Params) ->
EncodedParams = marchal_invoice_template_params(Params),
EncodedParams = marshal_invoice_template_params(Params),
map_start_error(hg_machine:start(?NS, ID, EncodedParams)).
call(ID, Function, Args) ->
@ -208,7 +208,7 @@ namespace() ->
-spec init(binary(), hg_machine:machine()) -> hg_machine:result().
init(EncodedParams, #{id := ID}) ->
Params = unmarchal_invoice_template_params(EncodedParams),
Params = unmarshal_invoice_template_params(EncodedParams),
Tpl = create_invoice_template(ID, Params),
#{events => [marshal_event_payload([?tpl_created(Tpl)])]}.
@ -223,7 +223,8 @@ create_invoice_template(ID, P) ->
description = P#payproc_InvoiceTemplateCreateParams.description,
created_at = hg_datetime:format_now(),
details = P#payproc_InvoiceTemplateCreateParams.details,
context = P#payproc_InvoiceTemplateCreateParams.context
context = P#payproc_InvoiceTemplateCreateParams.context,
mutations = P#payproc_InvoiceTemplateCreateParams.mutations
}.
-spec process_repair(hg_machine:args(), hg_machine:machine()) -> no_return().
@ -272,7 +273,8 @@ merge_changes(
product = Product,
description = Description,
details = Details,
context = Context
context = Context,
mutations = Mutations
})
],
Tpl
@ -283,7 +285,8 @@ merge_changes(
{product, Product},
{description, Description},
{details, Details},
{context, Context}
{context, Context},
{mutations, Mutations}
],
lists:foldl(fun update_field/2, Tpl, Diff).
@ -300,12 +303,14 @@ update_field({description, V}, Tpl) ->
update_field({details, V}, Tpl) ->
Tpl#domain_InvoiceTemplate{details = V};
update_field({context, V}, Tpl) ->
Tpl#domain_InvoiceTemplate{context = V}.
Tpl#domain_InvoiceTemplate{context = V};
update_field({mutations, V}, Tpl) ->
Tpl#domain_InvoiceTemplate{mutations = V}.
%% Marshaling
-spec marchal_invoice_template_params(create_params()) -> binary().
marchal_invoice_template_params(Params) ->
-spec marshal_invoice_template_params(create_params()) -> binary().
marshal_invoice_template_params(Params) ->
Type = {struct, struct, {dmsl_payproc_thrift, 'InvoiceTemplateCreateParams'}},
hg_proto_utils:serialize(Type, Params).
@ -323,8 +328,8 @@ wrap_event_payload(Payload) ->
%% Unmashaling
-spec unmarchal_invoice_template_params(binary()) -> create_params().
unmarchal_invoice_template_params(EncodedParams) ->
-spec unmarshal_invoice_template_params(binary()) -> create_params().
unmarshal_invoice_template_params(EncodedParams) ->
Type = {struct, struct, {dmsl_payproc_thrift, 'InvoiceTemplateCreateParams'}},
hg_proto_utils:deserialize(Type, EncodedParams).

View File

@ -29,6 +29,7 @@
-export([make_invoice_tpl_create_params/5]).
-export([make_invoice_tpl_create_params/6]).
-export([make_invoice_tpl_create_params/7]).
-export([make_invoice_tpl_create_params/8]).
-export([make_invoice_tpl_details/2]).
-export([make_invoice_tpl_update_params/1]).
@ -361,6 +362,7 @@ create_client_w_context(RootUrl, WoodyCtx) ->
-type invoice_params_tpl() :: dmsl_payproc_thrift:'InvoiceWithTemplateParams'().
-type timestamp() :: integer().
-type context() :: dmsl_base_thrift:'Content'().
-type mutation() :: dmsl_domain_thrift:'InvoiceMutationParams'().
-type lifetime_interval() :: dmsl_domain_thrift:'LifetimeInterval'().
-type invoice_details() :: dmsl_domain_thrift:'InvoiceDetails'().
-type invoice_tpl_details() :: dmsl_domain_thrift:'InvoiceTemplateDetails'().
@ -654,6 +656,19 @@ make_invoice_tpl_create_params(PartyID, ShopID, Lifetime, Product, Details, Cont
context()
) -> invoice_tpl_create_params().
make_invoice_tpl_create_params(InvoiceTemplateID, PartyID, ShopID, Lifetime, Product, Details, Context) ->
make_invoice_tpl_create_params(InvoiceTemplateID, PartyID, ShopID, Lifetime, Product, Details, Context, undefined).
-spec make_invoice_tpl_create_params(
invoice_template_id(),
party_id(),
shop_id(),
lifetime_interval(),
binary(),
invoice_tpl_details(),
context(),
[mutation()] | undefined
) -> invoice_tpl_create_params().
make_invoice_tpl_create_params(InvoiceTemplateID, PartyID, ShopID, Lifetime, Product, Details, Context, Mutations) ->
#payproc_InvoiceTemplateCreateParams{
template_id = InvoiceTemplateID,
party_id = PartyID,
@ -661,7 +676,8 @@ make_invoice_tpl_create_params(InvoiceTemplateID, PartyID, ShopID, Lifetime, Pro
invoice_lifetime = Lifetime,
product = Product,
details = Details,
context = Context
context = Context,
mutations = Mutations
}.
-spec make_invoice_tpl_details(binary(), invoice_tpl_cost()) -> invoice_tpl_details().
@ -685,7 +701,9 @@ update_field(product, V, Params) ->
update_field(description, V, Params) ->
Params#payproc_InvoiceTemplateUpdateParams{description = V};
update_field(context, V, Params) ->
Params#payproc_InvoiceTemplateUpdateParams{context = V}.
Params#payproc_InvoiceTemplateUpdateParams{context = V};
update_field(mutations, V, Params) ->
Params#payproc_InvoiceTemplateUpdateParams{mutations = V}.
-spec make_lifetime(non_neg_integer(), non_neg_integer(), non_neg_integer()) -> lifetime_interval().
make_lifetime(Y, M, D) ->

View File

@ -15,6 +15,7 @@
-export([create_invalid_cost_fixed_currency/1]).
-export([create_invalid_cost_range/1]).
-export([create_invoice_template/1]).
-export([create_invoice_template_with_mutations/1]).
-export([get_invoice_template_anyhow/1]).
-export([update_invalid_party_status/1]).
-export([update_invalid_shop_status/1]).
@ -23,6 +24,7 @@
-export([update_invalid_cost_range/1]).
-export([update_invoice_template/1]).
-export([update_with_cart/1]).
-export([update_with_mutations/1]).
-export([delete_invalid_party_status/1]).
-export([delete_invalid_shop_status/1]).
-export([delete_invoice_template/1]).
@ -54,6 +56,7 @@ all() ->
create_invalid_cost_fixed_currency,
create_invalid_cost_range,
create_invoice_template,
create_invoice_template_with_mutations,
get_invoice_template_anyhow,
update_invalid_party_status,
update_invalid_shop_status,
@ -62,6 +65,7 @@ all() ->
update_invalid_cost_range,
update_invoice_template,
update_with_cart,
update_with_mutations,
delete_invalid_party_status,
delete_invalid_shop_status,
delete_invoice_template,
@ -193,6 +197,17 @@ create_invoice_template(C) ->
ok = create_cost(make_cost(range, {inclusive, 42, <<"RUB">>}, {inclusive, 42, <<"RUB">>}), C),
ok = create_cost(make_cost(range, {inclusive, 42, <<"RUB">>}, {inclusive, 100, <<"RUB">>}), C).
-spec create_invoice_template_with_mutations(config()) -> _.
create_invoice_template_with_mutations(C) ->
Client = cfg(client, C),
Cost = make_cost(fixed, 42_00, <<"RUB">>),
Mutations = make_mutations(),
Product = <<"rubberduck">>,
Lifetime = make_lifetime(0, 0, 2),
#domain_InvoiceTemplate{id = TplID, mutations = Mutations} =
create_invoice_tpl_w_mutations(C, Product, Lifetime, Cost, Mutations),
#domain_InvoiceTemplate{mutations = Mutations} = hg_client_invoice_templating:get(TplID, Client).
create_cost(Cost, C) ->
Product = <<"rubberduck">>,
Details = hg_ct_helper:make_invoice_tpl_details(Product, Cost),
@ -204,6 +219,22 @@ create_cost(Cost, C) ->
} = create_invoice_tpl(C, Product, Lifetime, Cost),
ok.
make_mutations() ->
make_mutations(10_00).
make_mutations(Deviation) ->
[
{amount,
{randomization, #domain_RandomizationMutationParams{
deviation = Deviation,
precision = 2,
direction = both,
min_amount_condition = 1,
max_amount_condition = 10000_00,
amount_multiplicity_condition = 1
}}}
].
-spec get_invoice_template_anyhow(config()) -> _.
get_invoice_template_anyhow(C) ->
PartyID = cfg(party_id, C),
@ -379,6 +410,27 @@ update_with_cart(C) ->
} = hg_client_invoice_templating:update(TplID, Diff, Client),
#domain_InvoiceTemplate{} = hg_client_invoice_templating:get(TplID, Client).
-spec update_with_mutations(config()) -> _.
update_with_mutations(C) ->
Client = cfg(client, C),
Cost = make_cost(fixed, 42_00, <<"RUB">>),
Product = <<"rubberduck">>,
Lifetime = make_lifetime(0, 0, 2),
#domain_InvoiceTemplate{id = TplID, mutations = undefined} =
create_invoice_tpl_w_mutations(C, Product, Lifetime, Cost, undefined),
[
begin
Diff = make_invoice_tpl_update_params(#{mutations => M}),
#domain_InvoiceTemplate{mutations = M} =
hg_client_invoice_templating:update(TplID, Diff, Client)
end
|| M <- [
make_mutations(),
[],
make_mutations(420_00)
]
].
-spec delete_invalid_party_status(config()) -> _.
delete_invalid_party_status(C) ->
Client = cfg(client, C),
@ -484,6 +536,23 @@ create_invoice_tpl(Config, Product, Lifetime, Cost) ->
Params = make_invoice_tpl_create_params(PartyID, ShopID, Lifetime, Product, Details),
hg_client_invoice_templating:create(Params, Client).
create_invoice_tpl_w_mutations(Config, Product, Lifetime, Cost, Mutations) ->
Client = cfg(client, Config),
ShopID = cfg(shop_id, Config),
PartyID = cfg(party_id, Config),
Details = hg_ct_helper:make_invoice_tpl_details(Product, Cost),
Params = hg_ct_helper:make_invoice_tpl_create_params(
hg_utils:unique_id(),
PartyID,
ShopID,
Lifetime,
Product,
Details,
hg_ct_helper:make_invoice_context(),
Mutations
),
hg_client_invoice_templating:create(Params, Client).
update_invalid_cost(Cost, amount, TplID, Client) ->
update_invalid_cost(Cost, <<"Invalid amount">>, TplID, Client);
update_invalid_cost(Cost, currency, TplID, Client) ->

View File

@ -29,7 +29,8 @@
-export([invalid_shop_status/1]).
-export([invalid_invoice_template_cost/1]).
-export([invalid_invoice_template_id/1]).
-export([invoive_w_template_idempotency/1]).
-export([invoice_w_template_idempotency/1]).
-export([invoice_w_template_amount_randomization/1]).
-export([invoice_w_template/1]).
-export([invoice_cancellation/1]).
-export([overdue_invoice_cancellation/1]).
@ -308,7 +309,8 @@ groups() ->
invalid_invoice_currency,
invalid_invoice_template_cost,
invalid_invoice_template_id,
invoive_w_template_idempotency,
invoice_w_template_idempotency,
invoice_w_template_amount_randomization,
invoice_w_template,
invoice_cancellation,
overdue_invoice_cancellation,
@ -955,8 +957,8 @@ invalid_invoice_template_id(C) ->
Params2 = hg_ct_helper:make_invoice_params_tpl(TplID2),
{exception, #payproc_InvoiceTemplateRemoved{}} = hg_client_invoicing:create_with_tpl(Params2, Client).
-spec invoive_w_template_idempotency(config()) -> _ | no_return().
invoive_w_template_idempotency(C) ->
-spec invoice_w_template_idempotency(config()) -> _ | no_return().
invoice_w_template_idempotency(C) ->
Client = cfg(client, C),
TplCost1 = {_, FixedCost} = make_tpl_cost(fixed, 10000, <<"RUB">>),
TplContext1 = hg_ct_helper:make_invoice_context(<<"default context">>),
@ -999,6 +1001,48 @@ invoive_w_template_idempotency(C) ->
external_id = ExternalID
}) = hg_client_invoicing:create_with_tpl(Params2, Client).
-spec invoice_w_template_amount_randomization(config()) -> _.
invoice_w_template_amount_randomization(C) ->
Client = cfg(client, C),
OriginalAmount = 1500_00,
TplCost1 = {_, FixedCost} = make_tpl_cost(fixed, OriginalAmount, <<"RUB">>),
TplContext1 = hg_ct_helper:make_invoice_context(<<"default context">>),
TplClient = cfg(client_tpl, C),
PartyID = cfg(party_id, C),
ShopID = cfg(shop_id, C),
Lifetime = hg_ct_helper:make_lifetime(0, 1, 0),
Product = <<"rubberduck">>,
Details = hg_ct_helper:make_invoice_tpl_details(Product, TplCost1),
TplParams = #payproc_InvoiceTemplateCreateParams{
template_id = hg_utils:unique_id(),
party_id = PartyID,
shop_id = ShopID,
invoice_lifetime = Lifetime,
product = Product,
details = Details,
context = TplContext1,
mutations = [
{amount,
{randomization, #domain_RandomizationMutationParams{
deviation = 10_00,
precision = 2,
direction = downward,
min_amount_condition = 50_00,
max_amount_condition = 10000_00,
amount_multiplicity_condition = 100_00
}}}
]
},
#domain_InvoiceTemplate{id = TplID} = hg_client_invoice_templating:create(TplParams, TplClient),
InvoiceID = hg_utils:unique_id(),
Params = hg_ct_helper:make_invoice_params_tpl(InvoiceID, TplID, FixedCost, hg_ct_helper:make_invoice_context()),
?invoice_state(#domain_Invoice{mutations = Mutations}) = hg_client_invoicing:create_with_tpl(Params, Client),
?assertMatch(
[{amount, #domain_InvoiceAmountMutation{original = OriginalAmount, mutated = Mutated}}] when
Mutated =< OriginalAmount,
Mutations
).
-spec invoice_w_template(config()) -> _ | no_return().
invoice_w_template(C) ->
Client = cfg(client, C),