Compare commits
4 Commits
280c382a3d
...
3592e7747c
| Author | SHA1 | Date | |
|---|---|---|---|
| 3592e7747c | |||
| 7fe40faa9d | |||
| 02fd02dc21 | |||
| b884b82197 |
@ -1830,12 +1830,12 @@ func (h *MenuHandlers) ValidateAmount(ctx context.Context, sym string, input []b
|
|||||||
return res, fmt.Errorf("missing session")
|
return res, fmt.Errorf("missing session")
|
||||||
}
|
}
|
||||||
flag_invalid_amount, _ := h.flagManager.GetFlag("flag_invalid_amount")
|
flag_invalid_amount, _ := h.flagManager.GetFlag("flag_invalid_amount")
|
||||||
store := h.userdataStore
|
userStore := h.userdataStore
|
||||||
|
|
||||||
var balanceValue float64
|
var balanceValue float64
|
||||||
|
|
||||||
// retrieve the active balance
|
// retrieve the active balance
|
||||||
activeBal, err := store.ReadEntry(ctx, sessionId, storedb.DATA_ACTIVE_BAL)
|
activeBal, err := userStore.ReadEntry(ctx, sessionId, storedb.DATA_ACTIVE_BAL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logg.ErrorCtxf(ctx, "failed to read activeBal entry with", "key", storedb.DATA_ACTIVE_BAL, "error", err)
|
logg.ErrorCtxf(ctx, "failed to read activeBal entry with", "key", storedb.DATA_ACTIVE_BAL, "error", err)
|
||||||
return res, err
|
return res, err
|
||||||
@ -1862,11 +1862,14 @@ func (h *MenuHandlers) ValidateAmount(ctx context.Context, sym string, input []b
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Format the amount to 2 decimal places before saving (truncated)
|
// Format the amount to 2 decimal places before saving (truncated)
|
||||||
cents := int((inputAmount + 1e-9) * 100)
|
formattedAmount, err := store.TruncateDecimalString(amountStr, 2)
|
||||||
truncated := float64(cents) / 100
|
if err != nil {
|
||||||
formattedAmount := fmt.Sprintf("%.2f", truncated)
|
res.FlagSet = append(res.FlagSet, flag_invalid_amount)
|
||||||
|
res.Content = amountStr
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
err = store.WriteEntry(ctx, sessionId, storedb.DATA_AMOUNT, []byte(formattedAmount))
|
err = userStore.WriteEntry(ctx, sessionId, storedb.DATA_AMOUNT, []byte(formattedAmount))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logg.ErrorCtxf(ctx, "failed to write amount entry with", "key", storedb.DATA_AMOUNT, "value", formattedAmount, "error", err)
|
logg.ErrorCtxf(ctx, "failed to write amount entry with", "key", storedb.DATA_AMOUNT, "value", formattedAmount, "error", err)
|
||||||
return res, err
|
return res, err
|
||||||
@ -3049,7 +3052,15 @@ func (h *MenuHandlers) SwapPreview(ctx context.Context, sym string, input []byte
|
|||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
finalAmountStr, err := store.ParseAndScaleAmount(inputStr, swapData.ActiveSwapFromDecimal)
|
// Format the amount to 2 decimal places
|
||||||
|
formattedAmount, err := store.TruncateDecimalString(inputStr, 2)
|
||||||
|
if err != nil {
|
||||||
|
res.FlagSet = append(res.FlagSet, flag_invalid_amount)
|
||||||
|
res.Content = inputStr
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
finalAmountStr, err := store.ParseAndScaleAmount(formattedAmount, swapData.ActiveSwapFromDecimal)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1686,6 +1686,14 @@ func TestValidateAmount(t *testing.T) {
|
|||||||
Content: "0.14",
|
Content: "0.14",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "Test with valid large decimal amount",
|
||||||
|
input: []byte("1.8599999999"),
|
||||||
|
activeBal: []byte("5"),
|
||||||
|
expectedResult: resource.Result{
|
||||||
|
Content: "1.85",
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
|
|||||||
@ -7,6 +7,109 @@ import (
|
|||||||
"github.com/alecthomas/assert/v2"
|
"github.com/alecthomas/assert/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func TestTruncateDecimalString(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
input string
|
||||||
|
decimalPlaces int
|
||||||
|
want string
|
||||||
|
expectError bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "whole number",
|
||||||
|
input: "4",
|
||||||
|
decimalPlaces: 2,
|
||||||
|
want: "4.00",
|
||||||
|
expectError: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "single decimal",
|
||||||
|
input: "4.1",
|
||||||
|
decimalPlaces: 2,
|
||||||
|
want: "4.10",
|
||||||
|
expectError: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "one decimal place",
|
||||||
|
input: "4.19",
|
||||||
|
decimalPlaces: 1,
|
||||||
|
want: "4.1",
|
||||||
|
expectError: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "truncates to 2 dp",
|
||||||
|
input: "0.149",
|
||||||
|
decimalPlaces: 2,
|
||||||
|
want: "0.14",
|
||||||
|
expectError: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "does not round",
|
||||||
|
input: "1.8599999999",
|
||||||
|
decimalPlaces: 2,
|
||||||
|
want: "1.85",
|
||||||
|
expectError: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "high precision input",
|
||||||
|
input: "123.456789",
|
||||||
|
decimalPlaces: 4,
|
||||||
|
want: "123.4567",
|
||||||
|
expectError: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "zero",
|
||||||
|
input: "0",
|
||||||
|
decimalPlaces: 2,
|
||||||
|
want: "0.00",
|
||||||
|
expectError: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "invalid input string",
|
||||||
|
input: "abc",
|
||||||
|
decimalPlaces: 2,
|
||||||
|
want: "",
|
||||||
|
expectError: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "edge rounding case",
|
||||||
|
input: "4.99999999",
|
||||||
|
decimalPlaces: 2,
|
||||||
|
want: "4.99",
|
||||||
|
expectError: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "small value",
|
||||||
|
input: "0.0001",
|
||||||
|
decimalPlaces: 2,
|
||||||
|
want: "0.00",
|
||||||
|
expectError: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
got, err := TruncateDecimalString(tt.input, tt.decimalPlaces)
|
||||||
|
|
||||||
|
if tt.expectError {
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("TruncateDecimalString(%q, %d) expected error, got nil", tt.input, tt.decimalPlaces)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("TruncateDecimalString(%q, %d) unexpected error: %v", tt.input, tt.decimalPlaces, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if got != tt.want {
|
||||||
|
t.Errorf("TruncateDecimalString(%q, %d) = %q, want %q", tt.input, tt.decimalPlaces, got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestParseAndScaleAmount(t *testing.T) {
|
func TestParseAndScaleAmount(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
@ -64,6 +167,20 @@ func TestParseAndScaleAmount(t *testing.T) {
|
|||||||
want: "0",
|
want: "0",
|
||||||
expectError: false,
|
expectError: false,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "high decimals",
|
||||||
|
amount: "1.85",
|
||||||
|
decimals: "18",
|
||||||
|
want: "1850000000000000000",
|
||||||
|
expectError: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "6 d.p",
|
||||||
|
amount: "2.32",
|
||||||
|
decimals: "6",
|
||||||
|
want: "2320000",
|
||||||
|
expectError: false,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user