Add possibility to accept time units as value when setting balance + tests. Fixes #3274

This commit is contained in:
ionutboangiu
2021-09-15 17:10:24 +03:00
committed by Dan Christian Bogos
parent 49c35236b2
commit 59566430bc
4 changed files with 122 additions and 1 deletions

View File

@@ -76,6 +76,7 @@ var (
testAccITMultipleBalanceWithoutTenant,
testAccITRemoveBalances,
testAccITAddVoiceBalanceWithDestinations,
testAccITSetBalanceWithTimeSuffix,
testAccITStopCgrEngine,
}
)
@@ -1350,3 +1351,44 @@ func testAccITAddVoiceBalanceWithDestinations(t *testing.T) {
t.Errorf("Expecting %+v, received: %+v", 0, rply)
}
}
func testAccITSetBalanceWithTimeSuffix(t *testing.T) {
var reply string
args := &utils.AttrSetBalance{
Tenant: "cgrates.org",
Account: "testAccSetBalanceTimeSuffix",
BalanceType: "*voice",
Balance: map[string]interface{}{
utils.ID: "testAccSetBalanceTimeSuffix",
utils.Weight: 10,
utils.Value: "120ms",
},
}
if err := accRPC.Call(utils.APIerSv1SetBalance, args, &reply); err != nil {
t.Error("Got error on SetBalance: ", err.Error())
} else if reply != utils.OK {
t.Errorf("Calling SetBalance received: %s", reply)
}
var acnt engine.Account
attrAcc := &utils.AttrGetAccount{
Tenant: accTenant,
Account: "testAccSetBalanceTimeSuffix",
}
if err := accRPC.Call(utils.APIerSv2GetAccount, attrAcc, &acnt); err != nil {
t.Fatal(err)
}
for _, value := range acnt.BalanceMap[utils.MetaVoice] {
// check only where balance ID is testBalanceID (SetBalance function call was made with this Balance ID)
if value.ID == "testAccSetBalanceTimeSuffix" {
if value.GetValue() != 120000000. {
t.Errorf("Expecting %+v, received: %+v", 120000000., value.GetValue())
}
if value.Weight != 10 {
t.Errorf("Expecting %+v, received: %+v", 10, value.Weight)
}
break
}
}
}

View File

@@ -58,7 +58,7 @@ func NewBalanceFilter(filter map[string]interface{}, defaultTimezone string) (bf
// }
if val, has := filter[utils.Value]; has {
var value float64
if value, err = utils.IfaceAsFloat64(val); err != nil {
if value, err = utils.IfaceAsTFloat64(val); err != nil {
return
}
bf.Value = &utils.ValueFormula{Static: math.Abs(value)}

View File

@@ -277,6 +277,30 @@ func IfaceAsFloat64(itm interface{}) (f float64, err error) {
}
return
}
func IfaceAsTFloat64(itm interface{}) (f float64, err error) {
switch it := itm.(type) {
case float64:
return it, nil
case time.Duration:
return float64(it.Nanoseconds()), nil
case int:
return float64(it), nil
case int64:
return float64(it), nil
case string:
if strings.HasSuffix(it, SSuffix) || strings.HasSuffix(it, MSuffix) || strings.HasSuffix(it, HSuffix) {
var tm time.Duration
if tm, err = time.ParseDuration(it); err != nil {
return
}
return float64(tm), nil
}
return strconv.ParseFloat(it, 64)
default:
err = fmt.Errorf("cannot convert field: %+v to float64", it)
}
return
}
func IfaceAsBool(itm interface{}) (b bool, err error) {
switch v := itm.(type) {

View File

@@ -1833,3 +1833,58 @@ func TestIfaceAsBigDefault(t *testing.T) {
t.Errorf("Expected %v but received %v", errExpect, err)
}
}
func TestIfaceAsTFloat64(t *testing.T) {
eFloat := 6.0
val := interface{}(6.0)
if itmConvert, err := IfaceAsTFloat64(val); err != nil {
t.Error(err)
} else if itmConvert != eFloat {
t.Errorf("received: %+v", itmConvert)
}
val = interface{}(6)
if itmConvert, err := IfaceAsTFloat64(val); err != nil {
t.Error(err)
} else if itmConvert != eFloat {
t.Errorf("received: %+v", itmConvert)
}
val = interface{}("6")
if itmConvert, err := IfaceAsTFloat64(val); err != nil {
t.Error(err)
} else if itmConvert != eFloat {
t.Errorf("received: %+v", itmConvert)
}
val = interface{}(int64(6))
if itmConvert, err := IfaceAsTFloat64(val); err != nil {
t.Error(err)
} else if itmConvert != eFloat {
t.Errorf("received: %+v", itmConvert)
}
val = interface{}("This is not a float")
if _, err := IfaceAsTFloat64(val); err == nil {
t.Error("expecting error")
}
val = interface{}(time.Duration(6))
if itmConvert, err := IfaceAsTFloat64(val); err != nil {
t.Error(err)
} else if itmConvert != eFloat {
t.Errorf("received: %+v", itmConvert)
}
eFloat = 6000000.
val = interface{}("6ms")
if itmConvert, err := IfaceAsTFloat64(val); err != nil {
t.Error(err)
} else if itmConvert != eFloat {
t.Errorf("received: %+v", itmConvert)
}
val = interface{}("6sss")
experr := `time: unknown unit "sss" in duration "6sss"`
if _, err := IfaceAsTFloat64(val); err == nil || err.Error() != experr {
t.Errorf("expected: <%+v>, \nreceived: <%+v>", experr, err)
}
val = false
experr = `cannot convert field: false to float64`
if _, err := IfaceAsTFloat64(val); err == nil || err.Error() != experr {
t.Errorf("expected: <%+v>, \nreceived: <%+v>", experr, err)
}
}