254 lines
8.7 KiB
Go
254 lines
8.7 KiB
Go
package sresponse
|
|
|
|
import (
|
|
"testing"
|
|
|
|
gatewayv1 "github.com/tech/sendico/pkg/proto/common/gateway/v1"
|
|
moneyv1 "github.com/tech/sendico/pkg/proto/common/money/v1"
|
|
orchestrationv2 "github.com/tech/sendico/pkg/proto/payments/orchestration/v2"
|
|
quotationv2 "github.com/tech/sendico/pkg/proto/payments/quotation/v2"
|
|
sharedv1 "github.com/tech/sendico/pkg/proto/payments/shared/v1"
|
|
)
|
|
|
|
func TestToUserVisibleOperationsFiltersByVisibility(t *testing.T) {
|
|
steps := []*orchestrationv2.StepExecution{
|
|
{
|
|
StepRef: "hidden",
|
|
ReportVisibility: orchestrationv2.ReportVisibility_REPORT_VISIBILITY_HIDDEN,
|
|
},
|
|
{
|
|
StepRef: "user",
|
|
StepCode: "hop.4.card_payout.send",
|
|
State: orchestrationv2.StepExecutionState_STEP_EXECUTION_STATE_RUNNING,
|
|
ReportVisibility: orchestrationv2.ReportVisibility_REPORT_VISIBILITY_USER,
|
|
},
|
|
{
|
|
StepRef: "unspecified",
|
|
StepCode: "hop.4.card_payout.observe",
|
|
State: orchestrationv2.StepExecutionState_STEP_EXECUTION_STATE_COMPLETED,
|
|
ReportVisibility: orchestrationv2.ReportVisibility_REPORT_VISIBILITY_UNSPECIFIED,
|
|
},
|
|
{
|
|
StepRef: "backoffice",
|
|
ReportVisibility: orchestrationv2.ReportVisibility_REPORT_VISIBILITY_BACKOFFICE,
|
|
},
|
|
}
|
|
|
|
ops := toUserVisibleOperations(steps, nil)
|
|
if len(ops) != 2 {
|
|
t.Fatalf("operations count mismatch: got=%d want=2", len(ops))
|
|
}
|
|
if got, want := ops[0].StepRef, "user"; got != want {
|
|
t.Fatalf("first operation step_ref mismatch: got=%q want=%q", got, want)
|
|
}
|
|
if got, want := ops[1].StepRef, "unspecified"; got != want {
|
|
t.Fatalf("second operation step_ref mismatch: got=%q want=%q", got, want)
|
|
}
|
|
}
|
|
|
|
func TestToPaymentFailureUsesVisibleOperationsOnly(t *testing.T) {
|
|
dto := toPayment(&orchestrationv2.Payment{
|
|
PaymentRef: "pay-1",
|
|
State: orchestrationv2.OrchestrationState_ORCHESTRATION_STATE_FAILED,
|
|
StepExecutions: []*orchestrationv2.StepExecution{
|
|
{
|
|
StepRef: "hidden_failed",
|
|
StepCode: "edge.1_2.ledger.debit",
|
|
State: orchestrationv2.StepExecutionState_STEP_EXECUTION_STATE_FAILED,
|
|
ReportVisibility: orchestrationv2.ReportVisibility_REPORT_VISIBILITY_HIDDEN,
|
|
Failure: &orchestrationv2.Failure{
|
|
Category: sharedv1.PaymentFailureCode_FAILURE_LEDGER,
|
|
Message: "internal hold release failure",
|
|
},
|
|
},
|
|
{
|
|
StepRef: "user_failed",
|
|
StepCode: "hop.4.card_payout.send",
|
|
State: orchestrationv2.StepExecutionState_STEP_EXECUTION_STATE_FAILED,
|
|
ReportVisibility: orchestrationv2.ReportVisibility_REPORT_VISIBILITY_USER,
|
|
Failure: &orchestrationv2.Failure{
|
|
Category: sharedv1.PaymentFailureCode_FAILURE_CHAIN,
|
|
Message: "card declined",
|
|
},
|
|
},
|
|
},
|
|
})
|
|
if dto == nil {
|
|
t.Fatal("expected non-nil payment dto")
|
|
}
|
|
if got, want := dto.FailureCode, "failure_chain"; got != want {
|
|
t.Fatalf("failure_code mismatch: got=%q want=%q", got, want)
|
|
}
|
|
if got, want := dto.FailureReason, "card declined"; got != want {
|
|
t.Fatalf("failure_reason mismatch: got=%q want=%q", got, want)
|
|
}
|
|
if len(dto.Operations) != 1 {
|
|
t.Fatalf("operations count mismatch: got=%d want=1", len(dto.Operations))
|
|
}
|
|
if got, want := dto.Operations[0].StepRef, "user_failed"; got != want {
|
|
t.Fatalf("visible operation mismatch: got=%q want=%q", got, want)
|
|
}
|
|
}
|
|
|
|
func TestToPaymentIgnoresHiddenFailures(t *testing.T) {
|
|
dto := toPayment(&orchestrationv2.Payment{
|
|
PaymentRef: "pay-2",
|
|
State: orchestrationv2.OrchestrationState_ORCHESTRATION_STATE_FAILED,
|
|
StepExecutions: []*orchestrationv2.StepExecution{
|
|
{
|
|
StepRef: "hidden_failed",
|
|
StepCode: "edge.1_2.ledger.release",
|
|
State: orchestrationv2.StepExecutionState_STEP_EXECUTION_STATE_FAILED,
|
|
ReportVisibility: orchestrationv2.ReportVisibility_REPORT_VISIBILITY_BACKOFFICE,
|
|
Failure: &orchestrationv2.Failure{
|
|
Category: sharedv1.PaymentFailureCode_FAILURE_LEDGER,
|
|
Message: "backoffice only failure",
|
|
},
|
|
},
|
|
},
|
|
})
|
|
if dto == nil {
|
|
t.Fatal("expected non-nil payment dto")
|
|
}
|
|
if got := dto.FailureCode; got != "" {
|
|
t.Fatalf("expected empty failure_code, got=%q", got)
|
|
}
|
|
if got := dto.FailureReason; got != "" {
|
|
t.Fatalf("expected empty failure_reason, got=%q", got)
|
|
}
|
|
if len(dto.Operations) != 0 {
|
|
t.Fatalf("expected no visible operations, got=%d", len(dto.Operations))
|
|
}
|
|
}
|
|
|
|
func TestToPaymentQuote_MapsIntentRef(t *testing.T) {
|
|
dto := toPaymentQuote("ationv2.PaymentQuote{
|
|
QuoteRef: "quote-1",
|
|
IntentRef: "intent-1",
|
|
})
|
|
if dto == nil {
|
|
t.Fatal("expected non-nil quote dto")
|
|
}
|
|
if got, want := dto.QuoteRef, "quote-1"; got != want {
|
|
t.Fatalf("quote_ref mismatch: got=%q want=%q", got, want)
|
|
}
|
|
if got, want := dto.IntentRef, "intent-1"; got != want {
|
|
t.Fatalf("intent_ref mismatch: got=%q want=%q", got, want)
|
|
}
|
|
}
|
|
|
|
func TestToPaymentOperation_MapsOperationRefAndGateway(t *testing.T) {
|
|
op := toPaymentOperation(&orchestrationv2.StepExecution{
|
|
StepRef: "step-1",
|
|
StepCode: "hop.4.card_payout.send",
|
|
State: orchestrationv2.StepExecutionState_STEP_EXECUTION_STATE_COMPLETED,
|
|
Refs: []*orchestrationv2.ExternalReference{
|
|
{
|
|
Rail: gatewayv1.Rail_RAIL_CARD,
|
|
GatewayInstanceId: "mcards",
|
|
Kind: "operation_ref",
|
|
Ref: "op-123",
|
|
},
|
|
},
|
|
}, nil)
|
|
|
|
if got, want := op.OperationRef, "op-123"; got != want {
|
|
t.Fatalf("operation_ref mismatch: got=%q want=%q", got, want)
|
|
}
|
|
if got, want := op.Gateway, "mntx_gateway"; got != want {
|
|
t.Fatalf("gateway mismatch: got=%q want=%q", got, want)
|
|
}
|
|
}
|
|
|
|
func TestToPaymentOperation_InfersGatewayFromStepCode(t *testing.T) {
|
|
op := toPaymentOperation(&orchestrationv2.StepExecution{
|
|
StepRef: "step-2",
|
|
StepCode: "edge.1_2.ledger.debit",
|
|
State: orchestrationv2.StepExecutionState_STEP_EXECUTION_STATE_COMPLETED,
|
|
}, nil)
|
|
|
|
if got := op.OperationRef; got != "" {
|
|
t.Fatalf("expected empty operation_ref, got=%q", got)
|
|
}
|
|
if got, want := op.Gateway, "ledger"; got != want {
|
|
t.Fatalf("gateway mismatch: got=%q want=%q", got, want)
|
|
}
|
|
}
|
|
|
|
func TestToPaymentOperation_DoesNotFallbackToCardPayoutRef(t *testing.T) {
|
|
op := toPaymentOperation(&orchestrationv2.StepExecution{
|
|
StepRef: "step-3",
|
|
StepCode: "hop.4.card_payout.send",
|
|
State: orchestrationv2.StepExecutionState_STEP_EXECUTION_STATE_COMPLETED,
|
|
Refs: []*orchestrationv2.ExternalReference{
|
|
{
|
|
Rail: gatewayv1.Rail_RAIL_CARD,
|
|
GatewayInstanceId: "mcards",
|
|
Kind: "card_payout_ref",
|
|
Ref: "payout-123",
|
|
},
|
|
},
|
|
}, nil)
|
|
|
|
if got := op.OperationRef; got != "" {
|
|
t.Fatalf("expected empty operation_ref, got=%q", got)
|
|
}
|
|
if got, want := op.Gateway, "mntx_gateway"; got != want {
|
|
t.Fatalf("gateway mismatch: got=%q want=%q", got, want)
|
|
}
|
|
}
|
|
|
|
func TestToPaymentOperation_MapsAmount(t *testing.T) {
|
|
op := toPaymentOperation(&orchestrationv2.StepExecution{
|
|
StepRef: "step-4",
|
|
StepCode: "hop.4.card_payout.send",
|
|
State: orchestrationv2.StepExecutionState_STEP_EXECUTION_STATE_COMPLETED,
|
|
}, "ationv2.PaymentQuote{
|
|
TransferPrincipalAmount: &moneyv1.Money{Amount: "110.00", Currency: "USDT"},
|
|
DestinationAmount: &moneyv1.Money{Amount: "100.00", Currency: "EUR"},
|
|
})
|
|
|
|
if op.Amount == nil {
|
|
t.Fatal("expected amount to be mapped")
|
|
}
|
|
if got, want := op.Amount.Amount, "100.00"; got != want {
|
|
t.Fatalf("amount.value mismatch: got=%q want=%q", got, want)
|
|
}
|
|
if got, want := op.Amount.Currency, "EUR"; got != want {
|
|
t.Fatalf("amount.currency mismatch: got=%q want=%q", got, want)
|
|
}
|
|
if got := op.ConvertedAmount; got != nil {
|
|
t.Fatalf("expected no converted_amount for non-fx operation, got=%+v", got)
|
|
}
|
|
}
|
|
|
|
func TestToPaymentOperation_MapsFxTwoAmounts(t *testing.T) {
|
|
op := toPaymentOperation(&orchestrationv2.StepExecution{
|
|
StepRef: "step-5",
|
|
StepCode: "hop.2.settlement.fx_convert",
|
|
State: orchestrationv2.StepExecutionState_STEP_EXECUTION_STATE_COMPLETED,
|
|
}, "ationv2.PaymentQuote{
|
|
TransferPrincipalAmount: &moneyv1.Money{Amount: "110.00", Currency: "USDT"},
|
|
DestinationAmount: &moneyv1.Money{Amount: "100.00", Currency: "EUR"},
|
|
})
|
|
|
|
if op.Amount == nil {
|
|
t.Fatal("expected fx base amount to be mapped")
|
|
}
|
|
if got, want := op.Amount.Amount, "110.00"; got != want {
|
|
t.Fatalf("base amount.value mismatch: got=%q want=%q", got, want)
|
|
}
|
|
if got, want := op.Amount.Currency, "USDT"; got != want {
|
|
t.Fatalf("base amount.currency mismatch: got=%q want=%q", got, want)
|
|
}
|
|
if op.ConvertedAmount == nil {
|
|
t.Fatal("expected fx converted amount to be mapped")
|
|
}
|
|
if got, want := op.ConvertedAmount.Amount, "100.00"; got != want {
|
|
t.Fatalf("converted amount.value mismatch: got=%q want=%q", got, want)
|
|
}
|
|
if got, want := op.ConvertedAmount.Currency, "EUR"; got != want {
|
|
t.Fatalf("converted amount.currency mismatch: got=%q want=%q", got, want)
|
|
}
|
|
}
|