Files
cgrates/engine/libeventcost_test.go
2025-10-29 19:42:40 +01:00

1772 lines
43 KiB
Go

/*
Real-time Online/Offline Charging System (OCS) for Telecom & ISP environments
Copyright (C) ITsysCOM GmbH
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>
*/
package engine
import (
"errors"
"fmt"
"reflect"
"testing"
"time"
"github.com/cgrates/cgrates/utils"
)
// Start tests for ChargingInterval
func TestChargingIntervalPartiallyEquals(t *testing.T) {
ci1 := &ChargingInterval{
RatingID: "Rating1",
Increments: []*ChargingIncrement{
{
AccountingID: "Acc1",
CompressFactor: 2,
Cost: 2.345,
Usage: 2 * time.Second,
},
{
AccountingID: "Acc1",
CompressFactor: 2,
Cost: 1.23,
Usage: 5 * time.Second,
},
},
CompressFactor: 3,
}
ci2 := &ChargingInterval{
RatingID: "Rating1",
Increments: []*ChargingIncrement{
{
AccountingID: "Acc1",
CompressFactor: 2,
Cost: 2.345,
Usage: 2 * time.Second,
},
{
AccountingID: "Acc1",
CompressFactor: 2,
Cost: 1.23,
Usage: 5 * time.Second,
},
},
CompressFactor: 3,
}
if eq := ci1.PartiallyEquals(ci2); !eq {
t.Errorf("Expecting: true, received: %+v", eq)
}
ci2.RatingID = "Rating2"
if eq := ci1.PartiallyEquals(ci2); eq {
t.Errorf("Expecting: false, received: %+v", eq)
}
ci2.RatingID = "Rating1"
ci2.Increments[0].AccountingID = "Acc2"
if eq := ci1.PartiallyEquals(ci2); eq {
t.Errorf("Expecting: false, received: %+v", eq)
}
}
func TestChargingIntervalUsage(t *testing.T) {
ci1 := &ChargingInterval{
RatingID: "Rating1",
Increments: []*ChargingIncrement{
{
AccountingID: "Acc1",
CompressFactor: 2,
Cost: 2.345,
Usage: 2 * time.Second,
},
{
AccountingID: "Acc1",
CompressFactor: 2,
Cost: 1.23,
Usage: 5 * time.Second,
},
{
AccountingID: "Acc1",
CompressFactor: 3,
Cost: 1.23,
Usage: 4 * time.Millisecond,
},
},
CompressFactor: 3,
}
tCi1 := ci1.Usage()
eTCi1 := 14*time.Second + 12*time.Millisecond
if *tCi1 != eTCi1 {
t.Errorf("Expecting: %+v, received: %+v", eTCi1, *tCi1)
}
}
func TestChargingIntervalTotalUsage(t *testing.T) {
ci1 := &ChargingInterval{
RatingID: "Rating1",
Increments: []*ChargingIncrement{
{
AccountingID: "Acc1",
CompressFactor: 2,
Cost: 2.345,
Usage: 2 * time.Second,
},
{
AccountingID: "Acc1",
CompressFactor: 2,
Cost: 1.23,
Usage: 5 * time.Second,
},
{
AccountingID: "Acc1",
CompressFactor: 3,
Cost: 1.23,
Usage: 4 * time.Millisecond,
},
},
CompressFactor: 3,
}
tCi1 := ci1.TotalUsage()
eTCi1 := 3 * (14*time.Second + 12*time.Millisecond)
if *tCi1 != eTCi1 {
t.Errorf("Expecting: %+v, received: %+v", eTCi1, *tCi1)
}
}
func TestChargingIntervalEventCostUsageIndex(t *testing.T) {
ci1 := &ChargingInterval{
RatingID: "Rating1",
Increments: []*ChargingIncrement{
{
AccountingID: "Acc1",
CompressFactor: 2,
Cost: 2.345,
Usage: 2 * time.Second,
},
{
AccountingID: "Acc1",
CompressFactor: 2,
Cost: 1.23,
Usage: 5 * time.Second,
},
{
AccountingID: "Acc1",
CompressFactor: 3,
Cost: 1.23,
Usage: 4 * time.Millisecond,
},
},
CompressFactor: 3,
}
ci1.ecUsageIdx = ci1.TotalUsage()
tCi1 := ci1.EventCostUsageIndex()
eTCi1 := 3 * (14*time.Second + 12*time.Millisecond)
if *tCi1 != eTCi1 {
t.Errorf("Expecting: %+v, received: %+v", eTCi1, *tCi1)
}
}
func TestChargingIntervalStartTime(t *testing.T) {
ci1 := &ChargingInterval{
RatingID: "Rating1",
Increments: []*ChargingIncrement{
{
AccountingID: "Acc1",
CompressFactor: 2,
Cost: 2.345,
Usage: 2 * time.Second,
},
{
AccountingID: "Acc1",
CompressFactor: 2,
Cost: 1.23,
Usage: 5 * time.Second,
},
{
AccountingID: "Acc1",
CompressFactor: 3,
Cost: 1.23,
Usage: 4 * time.Millisecond,
},
},
CompressFactor: 3,
}
ci1.ecUsageIdx = ci1.TotalUsage()
tCi1 := ci1.StartTime(time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC))
eTCi1 := time.Date(2013, 11, 7, 8, 43, 8, 36000000, time.UTC)
if tCi1 != eTCi1 {
t.Errorf("Expecting: %+v, received: %+v", eTCi1, tCi1)
}
}
func TestChargingIntervalEndTime(t *testing.T) {
ci1 := &ChargingInterval{
RatingID: "Rating1",
Increments: []*ChargingIncrement{
{
AccountingID: "Acc1",
CompressFactor: 2,
Cost: 2.345,
Usage: 2 * time.Second,
},
{
AccountingID: "Acc1",
CompressFactor: 2,
Cost: 1.23,
Usage: 5 * time.Second,
},
{
AccountingID: "Acc1",
CompressFactor: 3,
Cost: 1.23,
Usage: 4 * time.Millisecond,
},
},
CompressFactor: 3,
}
ci1.ecUsageIdx = ci1.TotalUsage()
tCi1 := ci1.EndTime(time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC))
eTCi1 := time.Date(2013, 11, 7, 8, 43, 8, 36000000, time.UTC)
if tCi1 != eTCi1 {
t.Errorf("Expecting: %+v, received: %+v", eTCi1, tCi1)
}
}
func TestChargingIntervalCost(t *testing.T) {
ci1 := &ChargingInterval{
RatingID: "Rating1",
Increments: []*ChargingIncrement{
{
AccountingID: "Acc1",
CompressFactor: 2,
Cost: 2.345,
Usage: 2 * time.Second,
},
{
AccountingID: "Acc1",
CompressFactor: 2,
Cost: 1.23,
Usage: 5 * time.Second,
},
{
AccountingID: "Acc1",
CompressFactor: 3,
Cost: 1.23,
Usage: 4 * time.Millisecond,
},
},
CompressFactor: 3,
}
tCi1 := ci1.Cost()
eTCi1 := 10.84
if tCi1 != eTCi1 {
t.Errorf("Expecting: %+v, received: %+v", eTCi1, tCi1)
}
}
func TestChargingIntervalTotalCost(t *testing.T) {
ci1 := &ChargingInterval{
RatingID: "Rating1",
Increments: []*ChargingIncrement{
{
AccountingID: "Acc1",
CompressFactor: 2,
Cost: 2.345,
Usage: 2 * time.Second,
},
{
AccountingID: "Acc1",
CompressFactor: 2,
Cost: 1.23,
Usage: 5 * time.Second,
},
{
AccountingID: "Acc1",
CompressFactor: 3,
Cost: 1.23,
Usage: 4 * time.Millisecond,
},
},
CompressFactor: 3,
}
tCi1 := ci1.TotalCost()
eTCi1 := 32.52
if tCi1 != eTCi1 {
t.Errorf("Expecting: %+v, received: %+v", eTCi1, tCi1)
}
}
func TestChargingIntervalClone(t *testing.T) {
ci1 := &ChargingInterval{
RatingID: "Rating1",
Increments: []*ChargingIncrement{
{
AccountingID: "Acc1",
CompressFactor: 2,
Cost: 2.345,
Usage: 2 * time.Second,
},
{
AccountingID: "Acc1",
CompressFactor: 2,
Cost: 1.23,
Usage: 5 * time.Second,
},
{
AccountingID: "Acc1",
CompressFactor: 3,
Cost: 1.23,
Usage: 4 * time.Millisecond,
},
},
CompressFactor: 3,
}
ci2 := ci1.Clone()
if !reflect.DeepEqual(ci1, ci2) {
t.Errorf("Expecting: %+v, received: %+v", ci1, ci2)
}
ci1.RatingID = "Rating2"
if ci2.RatingID != "Rating1" {
t.Errorf("Expecting: Acc1, received: %+v", ci2)
}
}
// Start tests for ChargingIncrement
func TestChargingIncrementEquals(t *testing.T) {
ch1 := &ChargingIncrement{
AccountingID: "Acc1",
CompressFactor: 2,
Cost: 2.345,
Usage: 2 * time.Second,
}
ch2 := &ChargingIncrement{
AccountingID: "Acc1",
CompressFactor: 2,
Cost: 2.345,
Usage: 2 * time.Second,
}
ch3 := &ChargingIncrement{
AccountingID: "Acc2",
CompressFactor: 2,
Cost: 2.345,
Usage: 2 * time.Second,
}
if eq := ch1.Equals(ch2); !eq {
t.Errorf("Expecting: true, received: %+v", eq)
}
if eq := ch1.Equals(ch3); eq {
t.Errorf("Expecting: false, received: %+v", eq)
}
}
func TestChargingIncrementClone(t *testing.T) {
ch1 := &ChargingIncrement{
AccountingID: "Acc1",
CompressFactor: 2,
Cost: 2.345,
Usage: 2 * time.Second,
}
ch2 := ch1.Clone()
if !reflect.DeepEqual(ch1, ch2) {
t.Errorf("Expecting: %+v, received: %+v", ch2, ch1)
}
ch1.AccountingID = "Acc2"
if ch2.AccountingID != "Acc1" {
t.Errorf("Expecting: Acc1, received: %+v", ch1)
}
}
func TestChargingIncrementTotalUsage(t *testing.T) {
ch1 := &ChargingIncrement{
AccountingID: "Acc1",
CompressFactor: 2,
Cost: 2.345,
Usage: 2 * time.Second,
}
tCh1 := ch1.TotalUsage()
eTCh1 := 4 * time.Second
if tCh1 != eTCh1 {
t.Errorf("Expecting: %+v, received: %+v", eTCh1, tCh1)
}
}
func TestChargingIncrementTotalCost(t *testing.T) {
ch1 := &ChargingIncrement{
AccountingID: "Acc1",
CompressFactor: 2,
Cost: 2.345,
Usage: 2 * time.Second,
}
tCh1 := ch1.TotalCost()
eTCh1 := 4.69
if tCh1 != eTCh1 {
t.Errorf("Expecting: %+v, received: %+v", eTCh1, tCh1)
}
}
// Start tests for BalanceCharge
func TestBalanceChargeEquals(t *testing.T) {
bc1 := &BalanceCharge{
AccountID: "1001",
BalanceUUID: "ASD_FGH",
RatingID: "Rating1001",
Units: 2.34,
ExtraChargeID: "Extra1",
}
bc2 := &BalanceCharge{
AccountID: "1001",
BalanceUUID: "ASD_FGH",
RatingID: "Rating1001",
Units: 2.34,
ExtraChargeID: "Extra1",
}
bc3 := &BalanceCharge{
AccountID: "1002",
BalanceUUID: "ASD_FGH",
RatingID: "Rating1001",
Units: 2.34,
ExtraChargeID: "Extra1",
}
if eq := bc1.Equals(bc2); !eq {
t.Errorf("Expecting: true, received: %+v", eq)
}
if eq := bc1.Equals(bc3); eq {
t.Errorf("Expecting: false, received: %+v", eq)
}
}
func TestBalanceChargeClone(t *testing.T) {
bc1 := &BalanceCharge{
AccountID: "1001",
BalanceUUID: "ASD_FGH",
RatingID: "Rating1001",
Units: 2.34,
ExtraChargeID: "Extra1",
}
bc2 := bc1.Clone()
if !reflect.DeepEqual(bc1, bc2) {
t.Errorf("Expecting: %+v, received: %+v", bc1, bc2)
}
bc1.AccountID = "1002"
if bc2.AccountID != "1001" {
t.Errorf("Expecting: 1001, received: %+v", bc2)
}
}
// Start tests for RatingMatchedFilters
func TestRatingMatchedFiltersEquals(t *testing.T) {
rmf1 := RatingMatchedFilters{
"AccountID": "1001",
"Units": 2.34,
"ExtraChargeID": "Extra1",
}
rmf2 := RatingMatchedFilters{
"AccountID": "1001",
"Units": 2.34,
"ExtraChargeID": "Extra1",
}
rmf3 := RatingMatchedFilters{
"AccountID": "1002",
"Units": 2.34,
"ExtraChargeID": "Extra1",
}
if eq := rmf1.Equals(rmf2); !eq {
t.Errorf("Expecting: true, received: %+v", eq)
}
if eq := rmf1.Equals(rmf3); eq {
t.Errorf("Expecting: false, received: %+v", eq)
}
}
func TestRatingMatchedFiltersClone(t *testing.T) {
rmf1 := RatingMatchedFilters{
"AccountID": "1001",
"Units": 2.34,
"ExtraChargeID": "Extra1",
}
rmf2 := rmf1.Clone()
if eq := rmf1.Equals(rmf2); !eq {
t.Errorf("Expecting: true, received: %+v", eq)
}
rmf1["AccountID"] = "1002"
if rmf2["AccountID"] != "1001" {
t.Errorf("Expecting: 1001, received: %+v", rmf2)
}
}
// Start tests for ChargedTiming
func TestChargedTimingEquals(t *testing.T) {
ct1 := &ChargedTiming{
Years: utils.Years{1, 2},
Months: utils.Months{2, 3},
MonthDays: utils.MonthDays{4, 5},
WeekDays: utils.WeekDays{2, 3},
StartTime: "Time",
}
ct2 := &ChargedTiming{
Years: utils.Years{1, 2},
Months: utils.Months{2, 3},
MonthDays: utils.MonthDays{4, 5},
WeekDays: utils.WeekDays{2, 3},
StartTime: "Time",
}
ct3 := &ChargedTiming{
Years: utils.Years{2, 2},
Months: utils.Months{2, 3},
MonthDays: utils.MonthDays{4, 5},
WeekDays: utils.WeekDays{2, 3},
StartTime: "Time2",
}
if eq := ct1.Equals(ct2); !eq {
t.Errorf("Expecting: true, received: %+v", eq)
}
if eq := ct1.Equals(ct3); eq {
t.Errorf("Expecting: false, received: %+v", eq)
}
}
func TestChargedTimingClone(t *testing.T) {
ct1 := &ChargedTiming{
Years: utils.Years{1, 2},
Months: utils.Months{2, 3},
MonthDays: utils.MonthDays{4, 5},
WeekDays: utils.WeekDays{2, 3},
StartTime: "Time",
}
ct2 := ct1.Clone()
if eq := ct1.Equals(ct2); !eq {
t.Errorf("Expecting: true, received: %+v", eq)
}
ct1.StartTime = "Time2"
if ct2.StartTime != "Time" {
t.Errorf("Expecting: Time, received: %+v", ct2)
}
}
// Start tests for RatingUnit
func TestRatingUnitEquals(t *testing.T) {
ru1 := &RatingUnit{
ConnectFee: 1.23,
RoundingMethod: "Meth1",
RoundingDecimals: 4,
MaxCost: 3.45,
MaxCostStrategy: "MaxMeth",
TimingID: "TimingID1",
RatesID: "RatesID1",
RatingFiltersID: "RatingFltrID1",
}
ru2 := &RatingUnit{
ConnectFee: 1.23,
RoundingMethod: "Meth1",
RoundingDecimals: 4,
MaxCost: 3.45,
MaxCostStrategy: "MaxMeth",
TimingID: "TimingID1",
RatesID: "RatesID1",
RatingFiltersID: "RatingFltrID1",
}
ru3 := &RatingUnit{
ConnectFee: 1.24,
RoundingMethod: "Meth2",
RoundingDecimals: 4,
MaxCost: 3.45,
MaxCostStrategy: "MaxMeth",
TimingID: "TimingID1",
RatesID: "RatesID1",
RatingFiltersID: "RatingFltrID1",
}
if eq := ru1.Equals(ru2); !eq {
t.Errorf("Expecting: true, received: %+v", eq)
}
if eq := ru1.Equals(ru3); eq {
t.Errorf("Expecting: false, received: %+v", eq)
}
}
func TestRatingUnitClone(t *testing.T) {
ru1 := &RatingUnit{
ConnectFee: 1.23,
RoundingMethod: "Meth1",
RoundingDecimals: 4,
MaxCost: 3.45,
MaxCostStrategy: "MaxMeth",
TimingID: "TimingID1",
RatesID: "RatesID1",
RatingFiltersID: "RatingFltrID1",
}
ru2 := ru1.Clone()
if eq := ru1.Equals(ru2); !eq {
t.Errorf("Expecting: true, received: %+v", eq)
}
ru1.ConnectFee = 2.34
if ru2.ConnectFee != 1.23 {
t.Errorf("Expecting: 1.23, received: %+v", ru2)
}
}
// Start tests for RatingFilters
func TestRatingFiltersGetIDWithSet(t *testing.T) {
rf1 := RatingFilters{
"Key1": RatingMatchedFilters{
"AccountID": "1001",
"Units": 2.34,
"ExtraChargeID": "Extra1",
},
"Key2": RatingMatchedFilters{
"AccountID": "1002",
"Units": 1.23,
"ExtraChargeID": "Extra2",
},
}
if id1 := rf1.GetIDWithSet(RatingMatchedFilters{
"AccountID": "1001",
"Units": 2.34,
"ExtraChargeID": "Extra1",
}); id1 != "Key1" {
t.Errorf("Expecting: Key1, received: %+v", id1)
}
if id2 := rf1.GetIDWithSet(RatingMatchedFilters{
"AccountID": "1004",
"Units": 2.34,
"ExtraChargeID": "Extra3",
}); id2 == "" {
t.Errorf("Expecting id , received: %+v", id2)
}
if id3 := rf1.GetIDWithSet(nil); id3 != "" {
t.Errorf("Expecting , received: %+v", id3)
}
}
func TestRatingFiltersClone(t *testing.T) {
rf1 := RatingFilters{
"Key1": RatingMatchedFilters{
"AccountID": "1001",
"Units": 2.34,
"ExtraChargeID": "Extra1",
},
"Key2": RatingMatchedFilters{
"AccountID": "1002",
"Units": 1.23,
"ExtraChargeID": "Extra2",
},
}
rf2 := rf1.Clone()
if !reflect.DeepEqual(rf1, rf2) {
t.Errorf("Expecting: %+v, received: %+v", rf1, rf2)
}
rf1["Key1"]["AccountID"] = "1003"
if rf2["Key1"]["AccountID"] != "1001" {
t.Errorf("Expecting 1001 , received: %+v", rf2)
}
}
// Start tests for Rating
func TestRatingGetIDWithSet(t *testing.T) {
r1 := Rating{
"Key1": &RatingUnit{
ConnectFee: 1.23,
RoundingMethod: "Meth1",
RoundingDecimals: 4,
MaxCost: 3.45,
MaxCostStrategy: "MaxMeth",
TimingID: "TimingID1",
RatesID: "RatesID1",
RatingFiltersID: "RatingFltrID1",
},
"Key2": &RatingUnit{
ConnectFee: 0.2,
RoundingMethod: "Meth1",
RoundingDecimals: 4,
MaxCost: 2.12,
MaxCostStrategy: "MaxMeth",
TimingID: "TimingID1",
RatesID: "RatesID1",
RatingFiltersID: "RatingFltrID1",
},
}
if id1 := r1.GetIDWithSet(&RatingUnit{
ConnectFee: 1.23,
RoundingMethod: "Meth1",
RoundingDecimals: 4,
MaxCost: 3.45,
MaxCostStrategy: "MaxMeth",
TimingID: "TimingID1",
RatesID: "RatesID1",
RatingFiltersID: "RatingFltrID1",
}); id1 != "Key1" {
t.Errorf("Expecting: Key1, received: %+v", id1)
}
if id2 := r1.GetIDWithSet(&RatingUnit{
ConnectFee: 0.23,
RoundingMethod: "Meth1",
RoundingDecimals: 4,
MaxCost: 3.45,
MaxCostStrategy: "MaxMeth",
TimingID: "TimingID1",
RatesID: "RatesID1",
RatingFiltersID: "RatingFltrID1",
}); id2 == "" {
t.Errorf("Expecting id , received: %+v", id2)
}
if id3 := r1.GetIDWithSet(nil); id3 != "" {
t.Errorf("Expecting , received: %+v", id3)
}
}
func TestRatingClone(t *testing.T) {
rf1 := Rating{
"Key1": &RatingUnit{
ConnectFee: 1.23,
RoundingMethod: "Meth1",
RoundingDecimals: 4,
MaxCost: 3.45,
MaxCostStrategy: "MaxMeth",
TimingID: "TimingID1",
RatesID: "RatesID1",
RatingFiltersID: "RatingFltrID1",
},
"Key2": &RatingUnit{
ConnectFee: 0.2,
RoundingMethod: "Meth1",
RoundingDecimals: 4,
MaxCost: 2.12,
MaxCostStrategy: "MaxMeth",
TimingID: "TimingID1",
RatesID: "RatesID1",
RatingFiltersID: "RatingFltrID1",
},
}
rf2 := rf1.Clone()
if !reflect.DeepEqual(rf1, rf2) {
t.Errorf("Expecting: %+v, received: %+v", rf1, rf2)
}
rf1["Key1"].RatesID = "RatesID2"
if rf2["Key1"].RatesID != "RatesID1" {
t.Errorf("Expecting RatesID1 , received: %+v", rf2)
}
}
// Start tests for ChargedRates
func TestChargedRatesGetIDWithSet(t *testing.T) {
cr1 := ChargedRates{
"Key1": RateGroups{
&RGRate{
GroupIntervalStart: time.Hour,
Value: 0.17,
RateIncrement: time.Second,
RateUnit: time.Minute,
},
&RGRate{
GroupIntervalStart: time.Hour,
Value: 0.17,
RateIncrement: time.Second,
RateUnit: time.Minute,
},
},
"Key2": RateGroups{
&RGRate{
GroupIntervalStart: time.Hour,
Value: 1.12,
RateIncrement: time.Second,
RateUnit: time.Minute,
},
&RGRate{
GroupIntervalStart: 0,
Value: 2,
RateIncrement: time.Second,
RateUnit: time.Minute,
},
},
}
if id1 := cr1.GetIDWithSet(RateGroups{
&RGRate{
GroupIntervalStart: time.Hour,
Value: 0.17,
RateIncrement: time.Second,
RateUnit: time.Minute,
},
&RGRate{
GroupIntervalStart: time.Hour,
Value: 0.17,
RateIncrement: time.Second,
RateUnit: time.Minute,
},
}); id1 != "Key1" {
t.Errorf("Expecting: Key1, received: %+v", id1)
}
id2 := cr1.GetIDWithSet(RateGroups{
&RGRate{
GroupIntervalStart: time.Hour,
Value: 1,
RateIncrement: time.Second,
RateUnit: time.Minute,
},
&RGRate{
GroupIntervalStart: 0,
Value: 2,
RateIncrement: time.Second,
RateUnit: time.Minute,
},
})
if id2 == "" {
t.Errorf("Expecting id , received: %+v", id2)
}
if id3 := cr1.GetIDWithSet(nil); id3 != "" {
t.Errorf("Expecting , received: %+v", id3)
}
}
func TestChargedRatesClone(t *testing.T) {
cr1 := ChargedRates{
"Key1": RateGroups{
&RGRate{
GroupIntervalStart: time.Hour,
Value: 0.17,
RateIncrement: time.Second,
RateUnit: time.Minute,
},
&RGRate{
GroupIntervalStart: 0,
Value: 0.7,
RateIncrement: time.Second,
RateUnit: time.Minute,
},
},
"Key2": RateGroups{
&RGRate{
GroupIntervalStart: time.Hour,
Value: 1.12,
RateIncrement: time.Second,
RateUnit: time.Minute,
},
&RGRate{
GroupIntervalStart: 0,
Value: 2,
RateIncrement: time.Second,
RateUnit: time.Minute,
},
},
}
cr2 := cr1.Clone()
if !reflect.DeepEqual(cr1, cr2) {
t.Errorf("Expecting: %+v, received: %+v", cr1, cr2)
}
cr1["Key1"][0].Value = 12.2
if cr2["Key1"][0].Value != 0.17 {
t.Errorf("Expecting 0.17 , received: %+v", cr2)
}
}
// Start tests for ChargedTimings
func TestChargedTimingsGetIDWithSet(t *testing.T) {
ct1 := ChargedTimings{
"Key1": &ChargedTiming{
Years: utils.Years{2, 2},
Months: utils.Months{2, 3},
MonthDays: utils.MonthDays{1, 2, 3, 5},
WeekDays: utils.WeekDays{2, 3},
StartTime: "Time",
},
"Key2": &ChargedTiming{
Years: utils.Years{1, 2},
Months: utils.Months{2, 3},
MonthDays: utils.MonthDays{4, 5},
WeekDays: utils.WeekDays{2, 3},
StartTime: "Time",
},
}
if id1 := ct1.GetIDWithSet(&ChargedTiming{
Years: utils.Years{2, 2},
Months: utils.Months{2, 3},
MonthDays: utils.MonthDays{1, 2, 3, 5},
WeekDays: utils.WeekDays{2, 3},
StartTime: "Time",
}); id1 != "Key1" {
t.Errorf("Expecting: Key1, received: %+v", id1)
}
if id2 := ct1.GetIDWithSet(&ChargedTiming{
Years: utils.Years{1, 2, 3},
Months: utils.Months{2, 3},
MonthDays: utils.MonthDays{1, 2, 3, 5},
WeekDays: utils.WeekDays{2, 4, 3},
StartTime: "Time",
}); id2 == "" {
t.Errorf("Expecting id , received: %+v", id2)
}
if id3 := ct1.GetIDWithSet(nil); id3 != "" {
t.Errorf("Expecting , received: %+v", id3)
}
}
func TestChargedTimingsClone(t *testing.T) {
ct1 := ChargedTimings{
"Key1": &ChargedTiming{
Years: utils.Years{2, 2},
Months: utils.Months{2, 3},
MonthDays: utils.MonthDays{1, 2, 3, 5},
WeekDays: utils.WeekDays{2, 3},
StartTime: "Time",
},
"Key2": &ChargedTiming{
Years: utils.Years{1, 2},
Months: utils.Months{2, 3},
MonthDays: utils.MonthDays{4, 5},
WeekDays: utils.WeekDays{2, 3},
StartTime: "Time",
},
}
ct2 := ct1.Clone()
if !reflect.DeepEqual(ct1, ct2) {
t.Errorf("Expecting: %+v, received: %+v", ct1, ct2)
}
ct1["Key1"].StartTime = "Time2"
if ct2["Key1"].StartTime != "Time" {
t.Errorf("Expecting Time , received: %+v", ct2)
}
}
// Start tests for Accounting
func TestAccountingGetIDWithSet(t *testing.T) {
a1 := Accounting{
"Key1": &BalanceCharge{
AccountID: "1001",
BalanceUUID: "ASD_FGH",
RatingID: "Rating1001",
Units: 2.34,
ExtraChargeID: "Extra1",
},
"Key2": &BalanceCharge{
AccountID: "1002",
BalanceUUID: "ASD_FGH",
RatingID: "Rating1001",
Units: 1.23,
ExtraChargeID: "Extra1",
},
}
if id1 := a1.GetIDWithSet(&BalanceCharge{
AccountID: "1001",
BalanceUUID: "ASD_FGH",
RatingID: "Rating1001",
Units: 2.34,
ExtraChargeID: "Extra1",
}); id1 != "Key1" {
t.Errorf("Expecting: Key1, received: %+v", id1)
}
if id2 := a1.GetIDWithSet(&BalanceCharge{
AccountID: "1002",
BalanceUUID: "ASD_FGH",
RatingID: "Rating1001",
Units: 2.34,
ExtraChargeID: "Extra1",
}); id2 == "" {
t.Errorf("Expecting id , received: %+v", id2)
}
if id3 := a1.GetIDWithSet(nil); id3 != "" {
t.Errorf("Expecting , received: %+v", id3)
}
}
func TestAccountingClone(t *testing.T) {
a1 := Accounting{
"Key1": &BalanceCharge{
AccountID: "1001",
BalanceUUID: "ASD_FGH",
RatingID: "Rating1001",
Units: 2.34,
ExtraChargeID: "Extra1",
},
"Key2": &BalanceCharge{
AccountID: "1002",
BalanceUUID: "ASD_FGH",
RatingID: "Rating1001",
Units: 1.23,
ExtraChargeID: "Extra1",
},
}
a2 := a1.Clone()
if !reflect.DeepEqual(a1, a2) {
t.Errorf("Expecting: %+v, received: %+v", a1, a2)
}
a1["Key1"].AccountID = "1004"
if a2["Key1"].AccountID != "1001" {
t.Errorf("Expecting 1001 , received: %+v", a2)
}
}
func TestChargingIncrementFieldAsInterface(t *testing.T) {
cIt := &ChargingIncrement{
Usage: 1 * time.Minute,
Cost: 19,
AccountingID: "account_id",
CompressFactor: 1,
}
if _, err := cIt.FieldAsInterface([]string{utils.Usage, utils.Cost}); err == nil || err != utils.ErrNotFound {
t.Error(err)
} else if _, err = cIt.FieldAsInterface([]string{"default"}); err == nil {
t.Error(err)
} else if val, err := cIt.FieldAsInterface([]string{utils.Usage}); err != nil && val != cIt.Usage {
t.Error(err)
} else if val, err := cIt.FieldAsInterface([]string{utils.Cost}); err != nil && val != cIt.Cost {
t.Error(err)
} else if val, err := cIt.FieldAsInterface([]string{utils.AccountingID}); err != nil && val != cIt.AccountingID {
t.Error(err)
} else if val, err := cIt.FieldAsInterface([]string{utils.CompressFactor}); err != nil && val != cIt.CompressFactor {
t.Error(err)
}
}
func TestBalanceChargeFieldAsInterface(t *testing.T) {
bc := &BalanceCharge{
AccountID: "ACC_ID",
BalanceUUID: "BAL_UUID",
RatingID: "Rating_ID",
Units: 10.0,
ExtraChargeID: "extra",
}
if _, err = bc.FieldAsInterface([]string{utils.AccountID, utils.BalanceUUID}); err == nil || err != utils.ErrNotFound {
t.Error(err)
} else if _, err = bc.FieldAsInterface([]string{"default"}); err == nil {
t.Error(err)
} else if val, err := bc.FieldAsInterface([]string{utils.AccountID}); err != nil && val != bc.AccountID {
t.Error(err)
} else if val, err := bc.FieldAsInterface([]string{utils.BalanceUUID}); err != nil && val != bc.BalanceUUID {
t.Error(err)
} else if val, err := bc.FieldAsInterface([]string{utils.RatingID}); err != nil && val != bc.RatingID {
t.Error(err)
} else if val, err := bc.FieldAsInterface([]string{utils.Units}); err != nil && val != bc.Units {
t.Error(err)
} else if val, err := bc.FieldAsInterface([]string{utils.ExtraChargeID}); err != nil && val != bc.Units {
t.Error(err)
}
}
func TestNewFreeEventCost(t *testing.T) {
cgrID := "testCGRID"
runID := "testRunID"
account := "testAccount"
tStart := time.Now()
usage := 5 * time.Second
eventCost := NewFreeEventCost(cgrID, runID, account, tStart, usage)
if eventCost == nil {
t.Errorf("Expected non-nil EventCost, got nil")
}
if eventCost.CGRID != cgrID {
t.Errorf("Expected CGRID %v, got %v", cgrID, eventCost.CGRID)
}
if eventCost.RunID != runID {
t.Errorf("Expected RunID %v, got %v", runID, eventCost.RunID)
}
if !eventCost.StartTime.Equal(tStart) {
t.Errorf("Expected StartTime %v, got %v", tStart, eventCost.StartTime)
}
if eventCost.Cost == nil || *eventCost.Cost != 0 {
t.Errorf("Expected Cost 0, got %v", *eventCost.Cost)
}
if len(eventCost.Charges) != 1 {
t.Errorf("Expected 1 charge, got %d", len(eventCost.Charges))
}
charge := eventCost.Charges[0]
if charge.RatingID != utils.MetaPause {
t.Errorf("Expected RatingID %v, got %v", utils.MetaPause, charge.RatingID)
}
if len(charge.Increments) != 1 {
t.Errorf("Expected 1 increment, got %d", len(charge.Increments))
}
increment := charge.Increments[0]
if increment.Usage != usage {
t.Errorf("Expected Usage %v, got %v", usage, increment.Usage)
}
if increment.AccountingID != utils.MetaPause {
t.Errorf("Expected AccountingID %v, got %v", utils.MetaPause, increment.AccountingID)
}
if increment.CompressFactor != 1 {
t.Errorf("Expected CompressFactor 1, got %v", increment.CompressFactor)
}
rating := eventCost.Rating[utils.MetaPause]
if rating.RoundingMethod != "*up" {
t.Errorf("Expected RoundingMethod *up, got %v", rating.RoundingMethod)
}
if rating.RoundingDecimals != 5 {
t.Errorf("Expected RoundingDecimals 5, got %v", rating.RoundingDecimals)
}
if rating.RatesID != utils.MetaPause {
t.Errorf("Expected RatesID %v, got %v", utils.MetaPause, rating.RatesID)
}
if rating.RatingFiltersID != utils.MetaPause {
t.Errorf("Expected RatingFiltersID %v, got %v", utils.MetaPause, rating.RatingFiltersID)
}
if rating.TimingID != utils.MetaPause {
t.Errorf("Expected TimingID %v, got %v", utils.MetaPause, rating.TimingID)
}
accounting := eventCost.Accounting[utils.MetaPause]
if accounting.AccountID != account {
t.Errorf("Expected AccountID %v, got %v", account, accounting.AccountID)
}
if accounting.RatingID != utils.MetaPause {
t.Errorf("Expected Accounting RatingID %v, got %v", utils.MetaPause, accounting.RatingID)
}
ratingFilters := eventCost.RatingFilters[utils.MetaPause]
if ratingFilters[utils.Subject] != "" {
t.Errorf("Expected empty Subject, got %v", ratingFilters[utils.Subject])
}
if ratingFilters[utils.DestinationPrefixName] != "" {
t.Errorf("Expected empty DestinationPrefixName, got %v", ratingFilters[utils.DestinationPrefixName])
}
if ratingFilters[utils.DestinationID] != "" {
t.Errorf("Expected empty DestinationID, got %v", ratingFilters[utils.DestinationID])
}
if ratingFilters[utils.RatingPlanID] != utils.MetaPause {
t.Errorf("Expected RatingPlanID %v, got %v", utils.MetaPause, ratingFilters[utils.RatingPlanID])
}
rates := eventCost.Rates[utils.MetaPause]
if len(rates) != 1 {
t.Errorf("Expected 1 rate, got %d", len(rates))
}
if rates[0].RateIncrement != 1 {
t.Errorf("Expected RateIncrement 1, got %v", rates[0].RateIncrement)
}
if rates[0].RateUnit != 1 {
t.Errorf("Expected RateUnit 1, got %v", rates[0].RateUnit)
}
timings := eventCost.Timings[utils.MetaPause]
if timings.StartTime != "00:00:00" {
t.Errorf("Expected StartTime 00:00:00, got %v", timings.StartTime)
}
if eventCost.cache == nil {
t.Errorf("Expected non-nil cache, got nil")
}
}
func TestIfaceAsEventCostMapStringAny(t *testing.T) {
input := map[string]any{
"CGRID": "testCGRID",
"RunID": "testRunID",
"StartTime": "2024-08-09T12:34:56Z",
"Cost": 0.0,
}
expectedCGRID := "testCGRID"
expectedRunID := "testRunID"
ec, err := IfaceAsEventCost(input)
if err != nil {
t.Errorf("Expected no error, got %v", err)
}
if ec == nil {
t.Errorf("Expected non-nil EventCost, got nil")
}
if ec.CGRID != expectedCGRID {
t.Errorf("Expected CGRID %v, got %v", expectedCGRID, ec.CGRID)
}
if ec.RunID != expectedRunID {
t.Errorf("Expected RunID %v, got %v", expectedRunID, ec.RunID)
}
}
func TestIfaceAsEventCostDefault(t *testing.T) {
input := 42
_, err := IfaceAsEventCost(input)
if err == nil {
t.Errorf("Expected error, got nil")
}
expectedErrMsg := fmt.Sprintf("cannot convert type %v to *EventCost", reflect.TypeOf(input).String())
if err.Error() == expectedErrMsg {
t.Errorf("Expected error message %v, got %v", expectedErrMsg, err.Error())
}
}
func TestFieldAsInterface(t *testing.T) {
cts := ChargedTimings{}
tests := []struct {
name string
cts ChargedTimings
fldPath []string
expected any
err error
}{
{
name: "nil ChargedTimings",
cts: nil,
fldPath: []string{"field1"},
expected: nil,
err: utils.ErrNotFound,
},
{
name: "empty field path",
cts: cts,
fldPath: []string{},
expected: nil,
err: utils.ErrNotFound,
},
{
name: "field not found",
cts: cts,
fldPath: []string{"nonexistentField"},
expected: nil,
err: utils.ErrNotFound,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
val, err := tt.cts.FieldAsInterface(tt.fldPath)
if err != tt.err {
t.Errorf("Expected error: %v, got: %v", tt.err, err)
}
if val != tt.expected {
t.Errorf("Expected value: %v, got: %v", tt.expected, val)
}
})
}
}
func TestChargedRatesFieldAsInterface(t *testing.T) {
rateGroup := []*RGRate{
{
GroupIntervalStart: 10 * time.Second,
Value: 1.5,
RateIncrement: 5 * time.Second,
RateUnit: 60 * time.Second,
},
{
GroupIntervalStart: 20 * time.Second,
Value: 2.0,
RateIncrement: 10 * time.Second,
RateUnit: 60 * time.Second,
},
}
crs := ChargedRates{
"rateGroup[0]": rateGroup,
"rateGroup": rateGroup,
}
tests := []struct {
name string
crs ChargedRates
fldPath []string
expected any
err error
}{
{
name: "nil ChargedRates",
crs: nil,
fldPath: []string{"rateGroup[0]"},
expected: nil,
err: utils.ErrNotFound,
},
{
name: "empty field path",
crs: crs,
fldPath: []string{},
expected: nil,
err: utils.ErrNotFound,
},
{
name: "rate group with valid index",
crs: crs,
fldPath: []string{"rateGroup[0]"},
expected: rateGroup[0],
err: nil,
},
{
name: "rate group with invalid index",
crs: crs,
fldPath: []string{"rateGroup[2]"},
expected: nil,
err: utils.ErrNotFound,
},
{
name: "non-existent rate group",
crs: crs,
fldPath: []string{"nonExistentGroup"},
expected: nil,
err: utils.ErrNotFound,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
val, err := tt.crs.FieldAsInterface(tt.fldPath)
if err != nil && err.Error() != tt.err.Error() {
t.Errorf("Expected error: %v, got: %v", tt.err, err)
}
if val != tt.expected {
t.Errorf("Expected value: %v, got: %v", tt.expected, val)
}
})
}
}
func TestRatingFiltersFieldAsInterface(t *testing.T) {
ratingFilters := RatingFilters{
"filterA": RatingMatchedFilters{
"subField1": "ValueA",
"subField2": 100,
},
"filterB": RatingMatchedFilters{
"subField1": "ValueB",
},
}
tests := []struct {
name string
rfs RatingFilters
fldPath []string
expected any
err error
}{
{
name: "nil RatingFilters",
rfs: nil,
fldPath: []string{"filterA"},
expected: nil,
err: utils.ErrNotFound,
},
{
name: "empty field path",
rfs: ratingFilters,
fldPath: []string{},
expected: nil,
err: utils.ErrNotFound,
},
{
name: "field found with nested path",
rfs: ratingFilters,
fldPath: []string{"filterA", "subField1"},
expected: "ValueA",
err: nil,
},
{
name: "field not found",
rfs: ratingFilters,
fldPath: []string{"nonExistent"},
expected: nil,
err: utils.ErrNotFound,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
val, err := tt.rfs.FieldAsInterface(tt.fldPath)
if !errors.Is(err, tt.err) {
t.Errorf("Expected error: %v, got: %v", tt.err, err)
}
if val != tt.expected {
t.Errorf("Expected value: %v, got: %v", tt.expected, val)
}
})
}
}
func TestRatingMatchedFiltersFieldAsInterface(t *testing.T) {
rmf := RatingMatchedFilters{
"field1": "value1",
"field2": 42,
"field3": true,
}
tests := []struct {
name string
rmf RatingMatchedFilters
fldPath []string
expected any
err error
}{
{
name: "Field exists",
rmf: rmf,
fldPath: []string{"field1"},
expected: "value1",
err: nil,
},
{
name: "Field exists with integer value",
rmf: rmf,
fldPath: []string{"field2"},
expected: 42,
err: nil,
},
{
name: "Field exists with boolean value",
rmf: rmf,
fldPath: []string{"field3"},
expected: true,
err: nil,
},
{
name: "Field does not exist",
rmf: rmf,
fldPath: []string{"fieldNotFound"},
expected: nil,
err: utils.ErrNotFound,
},
{
name: "Invalid field path length",
rmf: rmf,
fldPath: []string{"field1", "extra"},
expected: nil,
err: utils.ErrNotFound,
},
{
name: "Nil RatingMatchedFilters",
rmf: nil,
fldPath: []string{"field1"},
expected: nil,
err: utils.ErrNotFound,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
_, err := tt.rmf.FieldAsInterface(tt.fldPath)
if !errors.Is(err, tt.err) && (err == nil || tt.err == nil || err.Error() != tt.err.Error()) {
t.Errorf("Expected error: %v, got: %v", tt.err, err)
}
})
}
}
func TestFieldAsInterfaces(t *testing.T) {
tests := []struct {
name string
accounting Accounting
fldPath []string
expectErr bool
}{
{
name: "Non-existent path",
accounting: Accounting{"balance1": &BalanceCharge{AccountID: "1"}},
fldPath: []string{"balance2"},
expectErr: true,
},
{
name: "Nil value in map",
accounting: Accounting{"balance1": nil},
fldPath: []string{"balance1"},
expectErr: true,
},
{
name: "Valid key with non-nil value",
accounting: Accounting{"balance1": &BalanceCharge{AccountID: "1"}},
fldPath: []string{"balance1"},
expectErr: false,
},
{
name: "Nil Accounting map",
accounting: nil,
fldPath: []string{"balance1"},
expectErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
_, err := tt.accounting.FieldAsInterface(tt.fldPath)
if (err != nil) != tt.expectErr {
t.Errorf("expected error: %v, got: %v", tt.expectErr, err)
}
})
}
}
func TestBalanceCharge(t *testing.T) {
balanceCharge := BalanceCharge{
AccountID: "account123",
BalanceUUID: "uuid",
RatingID: "ID1001",
Units: 10.0,
BalanceFactor: 0.5,
ExtraChargeID: "1",
}
tests := []struct {
path []string
expect interface{}
}{
{[]string{"AccountID"}, "account123"},
{[]string{"BalanceUUID"}, "uuid"},
{[]string{"RatingID"}, "ID1001"},
{[]string{"Units"}, 10.0},
{[]string{"BalanceFactor"}, 0.5},
{[]string{"ExtraChargeID"}, "1"},
}
for _, test := range tests {
val, err := balanceCharge.FieldAsInterface(test.path)
if err != nil {
t.Errorf("Unexpected error for path %v: %v", test.path, err)
continue
}
if val != test.expect {
t.Errorf("Expected %v for path %v, got %v", test.expect, test.path, val)
}
}
_, err := balanceCharge.FieldAsInterface([]string{"invalid_field"})
if err == nil {
t.Error("Expected error for invalid field path")
}
_, err = balanceCharge.FieldAsInterface([]string{})
if err == nil {
t.Error("Expected error for empty field path")
}
balanceCharge.BalanceFactor = 0
val, err := balanceCharge.FieldAsInterface([]string{"BalanceFactor"})
if err != nil {
t.Errorf("Unexpected error for BalanceFactor: %v", err)
}
if val != 1.0 {
t.Errorf("Expected 1.0 for BalanceFactor, got %v", val)
}
}
func TestRatingFieldAsInterface(t *testing.T) {
rating := Rating{
"rating1": &RatingUnit{
ConnectFee: 1.23,
RoundingMethod: "ROUNDING",
RoundingDecimals: 2,
MaxCost: 100,
MaxCostStrategy: "CAP",
TimingID: "timing1",
RatesID: "rates1",
RatingFiltersID: "filters1",
},
}
tests := []struct {
path []string
expect interface{}
}{
{[]string{"rating1"}, rating["rating1"]},
{[]string{"rating1", "ConnectFee"}, 1.23},
{[]string{"rating1", "RoundingMethod"}, "ROUNDING"},
{[]string{"rating1", "RoundingDecimals"}, 2},
{[]string{"rating1", "MaxCost"}, 100.0},
{[]string{"rating1", "MaxCostStrategy"}, "CAP"},
{[]string{"rating1", "TimingID"}, "timing1"},
{[]string{"rating1", "RatesID"}, "rates1"},
{[]string{"rating1", "RatingFiltersID"}, "filters1"},
}
for _, test := range tests {
val, err := rating.FieldAsInterface(test.path)
if err != nil {
t.Errorf("Unexpected error for path %v: %v", test.path, err)
continue
}
if !reflect.DeepEqual(val, test.expect) {
t.Errorf("Expected %v for path %v, got %v", test.expect, test.path, val)
}
}
_, err := rating.FieldAsInterface([]string{"invalid_rating"})
if err == nil {
t.Error("Expected error for invalid rating ID")
}
_, err = rating.FieldAsInterface([]string{})
if err == nil {
t.Error("Expected error for empty field path")
}
_, err = rating.FieldAsInterface([]string{"rating1", "invalid_field"})
if err == nil {
t.Error("Expected error for invalid field within rating")
}
}
func TestBalanceChargesClone(t *testing.T) {
t.Run("Normal", func(t *testing.T) {
original := &BalanceCharge{
AccountID: "account1",
BalanceUUID: "uuid1",
RatingID: "rating1",
Units: 100.5,
BalanceFactor: 1.25,
ExtraChargeID: "extraCharge01",
}
cloned := original.Clone()
if cloned == nil {
t.Errorf("Expected cloned BalanceCharge to be non-nil, but got nil")
}
if cloned.AccountID != original.AccountID || cloned.BalanceUUID != original.BalanceUUID ||
cloned.RatingID != original.RatingID || cloned.Units != original.Units ||
cloned.BalanceFactor != original.BalanceFactor || cloned.ExtraChargeID != original.ExtraChargeID {
t.Errorf("Cloned BalanceCharge does not match original. Expected %+v, but got %+v", original, cloned)
}
if cloned == original {
t.Errorf("Expected original and cloned BalanceCharge to be different instances, but they are the same")
}
})
t.Run("NilReceiver", func(t *testing.T) {
var original *BalanceCharge
cloned := original.Clone()
if cloned != nil {
t.Errorf("Expected cloned BalanceCharge to be nil, but got %+v", cloned)
}
})
}
func TestFieldsAsInterfaces(t *testing.T) {
ct := &ChargedTiming{
Years: utils.Years{1, 2},
Months: utils.Months{2, 3},
MonthDays: utils.MonthDays{4, 5},
WeekDays: utils.WeekDays{2, 3},
StartTime: "Time",
}
tests := []struct {
name string
fldPath []string
expected any
expectErr bool
}{
{
name: "Years Field",
fldPath: []string{utils.YearsFieldName},
expected: ct.Years,
expectErr: false,
},
{
name: "Months Field",
fldPath: []string{utils.MonthsFieldName},
expected: ct.Months,
expectErr: false,
},
{
name: "MonthDays Field",
fldPath: []string{utils.MonthDaysFieldName},
expected: ct.MonthDays,
expectErr: false,
},
{
name: "WeekDays Field",
fldPath: []string{utils.WeekDaysFieldName},
expected: ct.WeekDays,
expectErr: false,
},
{
name: "StartTime Field",
fldPath: []string{utils.StartTime},
expected: ct.StartTime,
expectErr: false,
},
{
name: "Invalid Field",
fldPath: []string{"invalidField"},
expected: nil,
expectErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
val, err := ct.FieldAsInterface(tt.fldPath)
if tt.expectErr {
if err == nil {
t.Errorf("Expected error, got nil")
}
} else {
if err != nil {
t.Errorf("Expected no error, got %v", err)
}
if !reflect.DeepEqual(val, tt.expected) {
t.Errorf("Expected value %v, got %v", tt.expected, val)
}
}
})
}
}
func TestChargingIntervalTotalUsages(t *testing.T) {
cIl := &ChargingInterval{
RatingID: "RtID1",
Increments: []*ChargingIncrement{
{
Usage: 2 * time.Second,
Cost: 0.2,
AccountingID: "AccID1",
CompressFactor: 1,
},
{
Usage: 3 * time.Second,
Cost: 0.3,
AccountingID: "AccID2",
CompressFactor: 1,
},
},
CompressFactor: 2,
usage: nil,
}
expected := 10 * time.Second
result := cIl.TotalUsage()
if result == nil {
t.Errorf("Expected %v, but got nil", expected)
} else if *result != expected {
t.Errorf("Expected %v, but got %v", expected, *result)
}
manualUsage := 7 * time.Second
cIl.usage = &manualUsage
expected2 := 14 * time.Second
result2 := cIl.TotalUsage()
if result2 == nil {
t.Errorf("Expected %v, but got nil", expected2)
} else if *result2 != expected2 {
t.Errorf("Expected %v, but got %v", expected2, *result2)
}
zeroUsage := time.Duration(0)
cIl4 := &ChargingInterval{
RatingID: "RtID3",
CompressFactor: 5,
usage: &zeroUsage,
}
expected4 := time.Duration(0)
result3 := cIl4.TotalUsage()
if result3 == nil {
t.Errorf("Expected %v, but got nil", expected4)
} else if *result3 != expected4 {
t.Errorf("Expected %v, but got %v", expected4, *result3)
}
}