Files
sendico/api/payments/quotation/internal/service/quotation/internal_helpers_test.go
2026-02-24 18:33:12 +01:00

117 lines
3.3 KiB
Go

package quotation
import (
"testing"
fxv1 "github.com/tech/sendico/pkg/proto/common/fx/v1"
moneyv1 "github.com/tech/sendico/pkg/proto/common/money/v1"
quotationv2 "github.com/tech/sendico/pkg/proto/payments/quotation/v2"
sharedv1 "github.com/tech/sendico/pkg/proto/payments/shared/v1"
)
func TestResolvedFeeTreatmentForQuote(t *testing.T) {
cases := []struct {
name string
intent *sharedv1.PaymentIntent
want quotationv2.FeeTreatment
}{
{
name: "nil intent defaults",
intent: nil,
want: quotationv2.FeeTreatment_FEE_TREATMENT_ADD_TO_SOURCE,
},
{
name: "no attributes defaults",
intent: &sharedv1.PaymentIntent{},
want: quotationv2.FeeTreatment_FEE_TREATMENT_ADD_TO_SOURCE,
},
{
name: "snake key parsed",
intent: &sharedv1.PaymentIntent{
Attributes: map[string]string{
"fee_treatment": "deduct_from_destination",
},
},
want: quotationv2.FeeTreatment_FEE_TREATMENT_DEDUCT_FROM_DESTINATION,
},
{
name: "camel key parsed",
intent: &sharedv1.PaymentIntent{
Attributes: map[string]string{
"feeTreatment": "fee_treatment_deduct_from_destination",
},
},
want: quotationv2.FeeTreatment_FEE_TREATMENT_DEDUCT_FROM_DESTINATION,
},
{
name: "invalid value falls back to default",
intent: &sharedv1.PaymentIntent{
Attributes: map[string]string{
"fee_treatment": "something_else",
},
},
want: quotationv2.FeeTreatment_FEE_TREATMENT_ADD_TO_SOURCE,
},
{
name: "snake key takes precedence over camel key",
intent: &sharedv1.PaymentIntent{
Attributes: map[string]string{
"fee_treatment": "add_to_source",
"feeTreatment": "deduct_from_destination",
},
},
want: quotationv2.FeeTreatment_FEE_TREATMENT_ADD_TO_SOURCE,
},
{
name: "value is trimmed and case-insensitive",
intent: &sharedv1.PaymentIntent{
Attributes: map[string]string{
"fee_treatment": " FEE_TREATMENT_DEDUCT_FROM_DESTINATION ",
},
},
want: quotationv2.FeeTreatment_FEE_TREATMENT_DEDUCT_FROM_DESTINATION,
},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
got := resolvedFeeTreatmentForQuote(tc.intent)
if got != tc.want {
t.Fatalf("unexpected fee treatment: got=%s want=%s", got.String(), tc.want.String())
}
})
}
}
func TestShouldRequestFX_DoesNotDependOnRequiresFxFlag(t *testing.T) {
intent := &sharedv1.PaymentIntent{
Amount: &moneyv1.Money{Amount: "10", Currency: "USDT"},
SettlementCurrency: "USDT",
RequiresFx: true,
}
if got := shouldRequestFX(intent); got {
t.Fatalf("expected shouldRequestFX=false when only requires_fx=true without FX data")
}
}
func TestShouldRequestFX_UsesFXIntentOrCurrencyDifference(t *testing.T) {
withPair := &sharedv1.PaymentIntent{
Amount: &moneyv1.Money{Amount: "10", Currency: "USDT"},
Fx: &sharedv1.FXIntent{
Pair: &fxv1.CurrencyPair{Base: "USDT", Quote: "RUB"},
Side: fxv1.Side_SELL_BASE_BUY_QUOTE,
},
}
if got := shouldRequestFX(withPair); !got {
t.Fatalf("expected shouldRequestFX=true for explicit fx intent")
}
withDerived := &sharedv1.PaymentIntent{
Amount: &moneyv1.Money{Amount: "10", Currency: "USDT"},
SettlementCurrency: "RUB",
}
if got := shouldRequestFX(withDerived); !got {
t.Fatalf("expected shouldRequestFX=true for derived FX from currency mismatch")
}
}