diff --git a/engine/account_test.go b/engine/account_test.go index 8a127016f..043d9c962 100644 --- a/engine/account_test.go +++ b/engine/account_test.go @@ -3192,3 +3192,192 @@ func TestAccSetBalanceAction(t *testing.T) { t.Error(err) } } + +func TestAccEnableAccountAction(t *testing.T) { + cfg := config.NewDefaultCGRConfig() + tmpDm := dm + defer func() { + dm = tmpDm + }() + db := NewInternalDB(nil, nil, true, cfg.DataDbCfg().Items) + dm := NewDataManager(db, cfg.CacheCfg(), nil) + acc := &Account{ + ID: "cgrates.org:1001", + BalanceMap: map[string]Balances{ + utils.MetaVoice: { + &Balance{ + ID: "BALANCE_ID", + Value: 20 * float64(time.Second), + Weight: 10}, + &Balance{Value: 100 * float64(time.Second), + Weight: 20}, + }}, + ActionTriggers: ActionTriggers{ + &ActionTrigger{ + Balance: &BalanceFilter{ + ID: utils.StringPointer("BALANCE_ID"), + Type: utils.StringPointer(utils.MetaMonetary)}, + ThresholdValue: 100, + ThresholdType: utils.TriggerMinEventCounter, + ActionsID: "TEST_ACTIONS"}, + }, + UnitCounters: UnitCounters{ + utils.MetaVoice: []*UnitCounter{ + { + CounterType: "*event", + Counters: CounterFilters{ + &CounterFilter{ + Value: 0, + Filter: &BalanceFilter{ + ID: utils.StringPointer("BALANCE_ID"), + Type: utils.StringPointer(utils.MetaVoice), + DestinationIDs: utils.StringMapPointer(utils.NewStringMap("GERMANY_O2")), + }, + }, + }, + }, + }, + }, + } + acc2 := &Account{ + ID: "cgrates.org:1002", + BalanceMap: map[string]Balances{ + utils.MetaVoice: { + &Balance{ + ID: "BALANCE_ID", + Value: 20 * float64(time.Second), + Weight: 10}, + }}, + ActionTriggers: ActionTriggers{ + &ActionTrigger{ + Balance: &BalanceFilter{ + ID: utils.StringPointer("BALANCE_ID"), + Type: utils.StringPointer(utils.MetaVoice)}, + ThresholdValue: 100, + ThresholdType: utils.TriggerMinEventCounter, + ActionsID: "TEST_ACTIONS2"}, + }, + UnitCounters: UnitCounters{ + utils.MetaVoice: []*UnitCounter{ + { + CounterType: "*event", + Counters: CounterFilters{ + &CounterFilter{ + Value: 0, + Filter: &BalanceFilter{ + ID: utils.StringPointer("BALANCE_ID"), + Type: utils.StringPointer(utils.MetaVoice), + DestinationIDs: utils.StringMapPointer(utils.NewStringMap("GERMANY_O2")), + }, + }, + }, + }, + }, + }, + } + acc3 := &Account{ + ID: "cgrates.org:1003", + BalanceMap: map[string]Balances{ + utils.MetaVoice: { + &Balance{ + dirty: true, + ID: "BALANCE_ID", + Value: 150 * float64(time.Second), + Weight: 10}, + }}, + ActionTriggers: ActionTriggers{ + &ActionTrigger{ + Balance: &BalanceFilter{ + ID: utils.StringPointer("BALANCE_ID"), + Type: utils.StringPointer(utils.MetaVoice)}, + ThresholdValue: 100, + ThresholdType: utils.TriggerMaxBalance, + ActionsID: "TEST_ACTIONS3"}, + }, + } + testCases := []struct { + name string + account *Account + actions Actions + key string + actiontype string + }{ + {name: "Enable account action", + account: acc, + actions: Actions{ + &Action{ + ActionType: utils.MetaEnableAccount, + Filters: []string{"*gte:~*req.BalanceMap.*voice[0].Value:20"}, + Balance: &BalanceFilter{ + ID: utils.StringPointer("BALANCE_ID"), + Type: utils.StringPointer(utils.MetaVoice), + DestinationIDs: utils.StringMapPointer(utils.NewStringMap("GERMANY_O2")), + }, + Weight: 9, + }, + }, + key: "TEST_ACTIONS", + actiontype: utils.MetaEnableAccount, + }, + { + name: "Disable account action", + account: acc2, + actions: Actions{ + &Action{ + ActionType: utils.MetaDisableAccount, + Filters: []string{"*string:~*req.BalanceMap.*voice[0].ID:BALANCE_ID"}, + Balance: &BalanceFilter{ + ID: utils.StringPointer("BALANCE_ID"), + Type: utils.StringPointer(utils.MetaVoice), + DestinationIDs: utils.StringMapPointer(utils.NewStringMap("GERMANY_O2")), + }, + Weight: 9, + }, + }, + key: "TEST_ACTIONS2", + actiontype: utils.MetaDisableAccount, + }, + { + name: "Set recurrent Action", + account: acc3, + actions: Actions{ + &Action{ + ActionType: utils.MetaSetRecurrent, + Filters: []string{"*string:~*req.BalanceMap.*voice[0].ID:BALANCE_ID"}, + Balance: &BalanceFilter{ + ID: utils.StringPointer("BALANCE_ID"), + Type: utils.StringPointer(utils.MetaVoice), + DestinationIDs: utils.StringMapPointer(utils.NewStringMap("GERMANY_O2")), + }, + Weight: 9, + }, + }, + key: "TEST_ACTIONS3", + actiontype: utils.MetaSetRecurrent, + }, + } + SetDataStorage(dm) + for _, tc := range testCases { + dm.SetActions(tc.key, tc.actions) + t.Run(tc.name, func(t *testing.T) { + tc.account.ExecuteActionTriggers(&Action{}, NewFilterS(cfg, nil, dm)) + + switch tc.actiontype { + case utils.MetaEnableAccount: + if acc, err := dm.GetAccount(tc.account.ID); err != nil { + t.Error(err) + } else if acc.Disabled != false { + t.Errorf("account should be enabled") + } + + case utils.MetaDisableAccount: + if acc, err := dm.GetAccount(tc.account.ID); err != nil { + t.Error(err) + } else if acc.Disabled != true { + t.Errorf("account should be disabled") + } + } + + }) + } +} diff --git a/engine/calldesc_test.go b/engine/calldesc_test.go index dbf033e3f..70fc92052 100644 --- a/engine/calldesc_test.go +++ b/engine/calldesc_test.go @@ -2637,5 +2637,74 @@ func TestCDRefundIncrementWarning(t *testing.T) { } else if rcvLog := buf.String(); !strings.Contains(rcvLog, expLog) { t.Errorf("Logger %v doesn't contain %v", rcvLog, expLog) } - +} + +func TestCallDescGetRatingPlansForPrefix(t *testing.T) { + cfg := config.NewDefaultCGRConfig() + tmpDm := dm + defer func() { + dm = tmpDm + }() + db := NewInternalDB(nil, nil, true, cfg.DataDbCfg().Items) + dm := NewDataManager(db, cfg.CacheCfg(), nil) + cd := &CallDescriptor{ + Category: "call", + Tenant: "cgrates.org", + Subject: "1005", + Account: "1005", + Destination: "1004", + TimeStart: time.Date(2022, time.January, 7, 16, 60, 0, 0, time.UTC), + TimeEnd: time.Date(2022, time.January, 7, 16, 60, 0, 0, time.UTC), + LoopIndex: 1, + ToR: utils.MetaVoice, + RunID: utils.MetaRaw, + DurationIndex: time.Second, + } + dm.SetRatingProfile(&RatingProfile{ + Id: "*out:cgrates.org:call:1005", + RatingPlanActivations: RatingPlanActivations{&RatingPlanActivation{ + ActivationTime: time.Date(2015, 01, 01, 8, 0, 0, 0, time.UTC), + RatingPlanId: "RP_2CNT", + }}, + }) + dm.SetRatingPlan(&RatingPlan{ + Id: "RP_2CNT", + Timings: map[string]*RITiming{ + "30eab300": { + Years: utils.Years{}, + Months: utils.Months{}, + MonthDays: utils.MonthDays{}, + WeekDays: utils.WeekDays{}, + StartTime: "00:00:00", + }, + }, + Ratings: map[string]*RIRate{ + "b457f86d": { + Rates: []*RGRate{ + { + GroupIntervalStart: 0, + Value: 0, + RateIncrement: 60 * time.Second, + RateUnit: 60 * time.Second, + }, + }, + RoundingMethod: utils.MetaRoundingMiddle, + RoundingDecimals: 4, + }, + }, + DestinationRates: map[string]RPRateList{ + "DEST": []*RPRate{ + { + Timing: "30eab300", + Rating: "b457f86d", + Weight: 10, + }, + }, + }, + }) + dm.SetReverseDestination("DEST", []string{"1004"}, "") + SetDataStorage(dm) + if err, _ = cd.getRatingPlansForPrefix(cd.GetKey(cd.Subject), 1); err != nil { + t.Error(err) + } } diff --git a/engine/ratingprofile_test.go b/engine/ratingprofile_test.go index 0df479a81..30911214a 100644 --- a/engine/ratingprofile_test.go +++ b/engine/ratingprofile_test.go @@ -21,6 +21,7 @@ import ( "testing" "time" + "github.com/cgrates/cgrates/config" "github.com/cgrates/cgrates/utils" ) @@ -395,3 +396,70 @@ func TestRatingProfileSubjectPrefixMatching(t *testing.T) { } rpSubjectPrefixMatching = false } + +func TestRatingProfileGetRatingPlansPrefixAny(t *testing.T) { + cfg := config.NewDefaultCGRConfig() + tmpDm := dm + defer func() { + dm = tmpDm + }() + db := NewInternalDB(nil, nil, true, cfg.DataDbCfg().Items) + dm := NewDataManager(db, cfg.CacheCfg(), nil) + rpf := &RatingProfile{ + Id: "*out:cgrates.org:call:1001", + RatingPlanActivations: RatingPlanActivations{&RatingPlanActivation{ + ActivationTime: time.Date(2015, 01, 01, 8, 0, 0, 0, time.UTC), + RatingPlanId: "RP_2CNT", + }}, + } + cd := &CallDescriptor{ + ToR: "*prepaid", + Tenant: "cgrates.org", + Category: "call", Account: "1001", + Subject: "1001", Destination: "1003", + TimeStart: time.Date(2023, 11, 7, 8, 42, 26, 0, time.UTC), + TimeEnd: time.Date(2023, 11, 7, 8, 42, 26, 0, time.UTC).Add(50 * time.Second), + } + dm.SetRatingPlan(&RatingPlan{ + Id: "RP_2CNT", + Timings: map[string]*RITiming{ + "30eab300": { + Years: utils.Years{}, + Months: utils.Months{}, + MonthDays: utils.MonthDays{}, + WeekDays: utils.WeekDays{}, + StartTime: "00:00:00", + }, + }, + Ratings: map[string]*RIRate{ + "b457f86d": { + Rates: []*RGRate{ + { + GroupIntervalStart: 0, + Value: 0, + RateIncrement: 60 * time.Second, + RateUnit: 60 * time.Second, + }, + }, + RoundingMethod: utils.MetaRoundingMiddle, + RoundingDecimals: 4, + }, + }, + DestinationRates: map[string]RPRateList{ + "*any": []*RPRate{ + { + Timing: "30eab300", + Rating: "b457f86d", + Weight: 10, + }, + }, + }, + }) + + dm.SetReverseDestination("DEST", []string{"1003"}, "") + SetDataStorage(dm) + if err := rpf.GetRatingPlansForPrefix(cd); err != nil { + t.Error("Error getting rating plans for prefix: ", err) + } + +}