Files
cgrates/config/fctemplate_test.go
2025-10-13 09:57:41 +02:00

833 lines
25 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 config
import (
"reflect"
"testing"
"time"
"github.com/cgrates/cgrates/utils"
)
func TestNewFCTemplateFromFCTemplateJsonCfg(t *testing.T) {
jsonCfg := &FcTemplateJsonCfg{
Tag: utils.StringPointer("Tenant"),
Type: utils.StringPointer("*composed"),
Path: utils.StringPointer("Tenant"),
Filters: &[]string{"Filter1", "Filter2"},
Value: utils.StringPointer("cgrates.org"),
}
expected := &FCTemplate{
Tag: "Tenant",
Type: "*composed",
Path: "Tenant",
Filters: []string{"Filter1", "Filter2"},
Value: utils.NewRSRParsersMustCompile("cgrates.org", utils.InfieldSep),
Layout: time.RFC3339,
}
expected.ComputePath()
if rcv, err := NewFCTemplateFromFCTemplateJSONCfg(jsonCfg); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(expected, rcv) {
t.Errorf("expected: %s ,received: %s", utils.ToJSON(expected), utils.ToJSON(rcv))
}
}
func TestFCTemplateInflateTemplate(t *testing.T) {
fcTemplate := []*FCTemplate{
{
Type: utils.MetaTemplate,
Value: utils.NewRSRParsersMustCompile("1sa{*duration}", utils.InfieldSep),
},
}
expected := "time: unknown unit \"sa\" in duration \"1sa\""
jsonCfg := NewDefaultCGRConfig()
if _, err := InflateTemplates(fcTemplate, jsonCfg.templates); err == nil || err.Error() != expected {
t.Errorf("Expected %+v, received %+v", expected, err)
}
}
func TestFCTemplatePathItems(t *testing.T) {
fcTemplate := FCTemplate{
Path: "*req.Account[1].Balance[*monetary].Value",
}
expected := []string{"*req", "Account", "1", "Balance", "*monetary", "Value"}
fcTemplate.ComputePath()
if !reflect.DeepEqual(expected, fcTemplate.GetPathSlice()) {
t.Errorf("Expected %+v, received %+v", utils.ToJSON(expected), utils.ToJSON(fcTemplate))
}
}
func TestFCTemplatesFromFCTemplatesJsonCfg(t *testing.T) {
jsnCfgs := []*FcTemplateJsonCfg{
{
Tag: utils.StringPointer("Tenant"),
Type: utils.StringPointer("*composed"),
Path: utils.StringPointer("Tenant"),
Filters: &[]string{"Filter1", "Filter2"},
Value: utils.StringPointer("cgrates.org"),
},
{
Tag: utils.StringPointer("RunID"),
Type: utils.StringPointer("*composed"),
Path: utils.StringPointer("RunID"),
Filters: &[]string{"Filter1_1", "Filter2_2"},
Value: utils.StringPointer("SampleValue"),
},
}
expected := []*FCTemplate{
{
Tag: "Tenant",
Type: "*composed",
Path: "Tenant",
Filters: []string{"Filter1", "Filter2"},
Value: utils.NewRSRParsersMustCompile("cgrates.org", utils.InfieldSep),
Layout: time.RFC3339,
},
{
Tag: "RunID",
Type: "*composed",
Path: "RunID",
Filters: []string{"Filter1_1", "Filter2_2"},
Value: utils.NewRSRParsersMustCompile("SampleValue", utils.InfieldSep),
Layout: time.RFC3339,
},
}
for _, v := range expected {
v.ComputePath()
}
if rcv, err := FCTemplatesFromFCTemplatesJSONCfg(jsnCfgs); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(expected, rcv) {
t.Errorf("expected: %s ,received: %s", utils.ToJSON(expected), utils.ToJSON(rcv))
}
}
func TestFCTemplateInflate1(t *testing.T) {
fcTmp1 := []*FCTemplate{
{
Tag: "Tenant",
Type: "*composed",
Path: "Tenant",
Filters: []string{"Filter1", "Filter2"},
Value: utils.NewRSRParsersMustCompile("cgrates.org", utils.InfieldSep),
},
{
Tag: "RunID",
Type: "*composed",
Path: "RunID",
Filters: []string{"Filter1_1", "Filter2_2"},
Value: utils.NewRSRParsersMustCompile("SampleValue", utils.InfieldSep),
},
{
Tag: "TmpMap",
Type: "*template",
Filters: []string{"Filter1_1", "Filter2_2"},
Value: utils.NewRSRParsersMustCompile("TmpMap", utils.InfieldSep),
},
}
fcTmpMp := map[string][]*FCTemplate{
"TmpMap": {
{
Tag: "Elem1",
Type: "*composed",
Path: "Elem1",
Filters: []string{"Filter1", "Filter2"},
Value: utils.NewRSRParsersMustCompile("Elem1", utils.InfieldSep),
},
{
Tag: "Elem2",
Type: "*composed",
Path: "Elem2",
Filters: []string{"Filter1_1", "Filter2_2"},
Value: utils.NewRSRParsersMustCompile("Elem2", utils.InfieldSep),
},
},
"TmpMap2": {
{
Tag: "Elem2.1",
Type: "*composed",
Path: "Elem2.1",
Filters: []string{"Filter1", "Filter2"},
Value: utils.NewRSRParsersMustCompile("Elem2.1", utils.InfieldSep),
},
{
Tag: "Elem2.2",
Type: "*composed",
Path: "Elem2.2",
Filters: []string{"Filter1_1", "Filter2_2"},
Value: utils.NewRSRParsersMustCompile("Elem2.2", utils.InfieldSep),
},
},
}
expFC := []*FCTemplate{
{
Tag: "Tenant",
Type: "*composed",
Path: "Tenant",
Filters: []string{"Filter1", "Filter2"},
Value: utils.NewRSRParsersMustCompile("cgrates.org", utils.InfieldSep),
},
{
Tag: "RunID",
Type: "*composed",
Path: "RunID",
Filters: []string{"Filter1_1", "Filter2_2"},
Value: utils.NewRSRParsersMustCompile("SampleValue", utils.InfieldSep),
},
{
Tag: "Elem1",
Type: "*composed",
Path: "Elem1",
Filters: []string{"Filter1", "Filter2"},
Value: utils.NewRSRParsersMustCompile("Elem1", utils.InfieldSep),
},
{
Tag: "Elem2",
Type: "*composed",
Path: "Elem2",
Filters: []string{"Filter1_1", "Filter2_2"},
Value: utils.NewRSRParsersMustCompile("Elem2", utils.InfieldSep),
},
}
if rcv, err := InflateTemplates(fcTmp1, fcTmpMp); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(expFC, rcv) {
t.Errorf("expected: %s\n ,received: %s", utils.ToJSON(expFC), utils.ToJSON(rcv))
}
}
func TestFCTemplateInflate2(t *testing.T) {
fcTmp1 := []*FCTemplate{
{
Tag: "Tenant",
Type: "*composed",
Path: "Tenant",
Filters: []string{"Filter1", "Filter2"},
Value: utils.NewRSRParsersMustCompile("cgrates.org", utils.InfieldSep),
},
{
Tag: "RunID",
Type: "*composed",
Path: "RunID",
Filters: []string{"Filter1_1", "Filter2_2"},
Value: utils.NewRSRParsersMustCompile("SampleValue", utils.InfieldSep),
},
{
Tag: "TmpMap3",
Type: "*template",
Filters: []string{"Filter1_1", "Filter2_2"},
Value: utils.NewRSRParsersMustCompile("TmpMap3", utils.InfieldSep),
},
}
fcTmpMp := map[string][]*FCTemplate{
"TmpMap": {
{
Tag: "Elem1",
Type: "*composed",
Path: "Elem1",
Filters: []string{"Filter1", "Filter2"},
Value: utils.NewRSRParsersMustCompile("Elem1", utils.InfieldSep),
},
{
Tag: "Elem2",
Type: "*composed",
Path: "Elem2",
Filters: []string{"Filter1_1", "Filter2_2"},
Value: utils.NewRSRParsersMustCompile("Elem2", utils.InfieldSep),
},
},
"TmpMap2": {
{
Tag: "Elem2.1",
Type: "*composed",
Path: "Elem2.1",
Filters: []string{"Filter1", "Filter2"},
Value: utils.NewRSRParsersMustCompile("Elem2.1", utils.InfieldSep),
},
{
Tag: "Elem2.2",
Type: "*composed",
Path: "Elem2.2",
Filters: []string{"Filter1_1", "Filter2_2"},
Value: utils.NewRSRParsersMustCompile("Elem2.2", utils.InfieldSep),
},
},
}
expected := "no template with id: <TmpMap3>"
if _, err := InflateTemplates(fcTmp1, fcTmpMp); err == nil || err.Error() != expected {
t.Error(err)
}
}
func TestFCTemplateInflate3(t *testing.T) {
fcTmp1 := []*FCTemplate{
{
Tag: "Tenant",
Type: "*composed",
Path: "Tenant",
Filters: []string{"Filter1", "Filter2"},
Value: utils.NewRSRParsersMustCompile("cgrates.org", utils.InfieldSep),
},
{
Tag: "RunID",
Type: "*composed",
Path: "RunID",
Filters: []string{"Filter1_1", "Filter2_2"},
Value: utils.NewRSRParsersMustCompile("SampleValue", utils.InfieldSep),
},
{
Tag: "TmpMap",
Type: "*template",
Filters: []string{"Filter1_1", "Filter2_2"},
Value: utils.NewRSRParsersMustCompile("TmpMap", utils.InfieldSep),
},
}
fcTmpMp := map[string][]*FCTemplate{
"TmpMap": {},
"TmpMap2": {
{
Tag: "Elem2.1",
Type: "*composed",
Path: "Elem2.1",
Filters: []string{"Filter1", "Filter2"},
Value: utils.NewRSRParsersMustCompile("Elem2.1", utils.InfieldSep),
},
{
Tag: "Elem2.2",
Type: "*composed",
Path: "Elem2.2",
Filters: []string{"Filter1_1", "Filter2_2"},
Value: utils.NewRSRParsersMustCompile("Elem2.2", utils.InfieldSep),
},
},
}
for _, v := range fcTmp1 {
v.ComputePath()
}
for _, tmpl := range fcTmpMp {
for _, v := range tmpl {
v.ComputePath()
}
}
if _, err := InflateTemplates(fcTmp1, fcTmpMp); err == nil ||
err.Error() != "empty template with id: <TmpMap>" {
t.Error(err)
}
}
func TestFCTemplateClone(t *testing.T) {
smpl := &FCTemplate{
Tag: "Tenant",
Type: "*composed",
Path: "Tenant",
Filters: []string{"Filter1", "Filter2"},
Value: utils.NewRSRParsersMustCompile("cgrates.org", utils.InfieldSep),
RoundingDecimals: utils.IntPointer(2),
}
smpl.ComputePath()
cloned := smpl.Clone()
if !reflect.DeepEqual(cloned, smpl) {
t.Errorf("expected: %s ,received: %s", utils.ToJSON(smpl), utils.ToJSON(cloned))
}
initialSmpl := &FCTemplate{
Tag: "Tenant",
Type: "*composed",
Path: "Tenant",
Filters: []string{"Filter1", "Filter2"},
Value: utils.NewRSRParsersMustCompile("cgrates.org", utils.InfieldSep),
RoundingDecimals: utils.IntPointer(2),
}
initialSmpl.ComputePath()
smpl.Filters = []string{"SingleFilter"}
smpl.Value = utils.NewRSRParsersMustCompile("cgrates.com", utils.InfieldSep)
if !reflect.DeepEqual(cloned, initialSmpl) {
t.Errorf("expected: %s ,received: %s", utils.ToJSON(initialSmpl), utils.ToJSON(cloned))
}
}
func TestFCTemplateAsMapInterface(t *testing.T) {
cfgJSONStr := `{
"templates": {
"custom_template": [
{
"tag": "Tenant",
"type": "*composed",
"path": "Tenant",
"filters" : ["val1","val2"],
"value": "cgrates.org",
"width": 10,
"strip": "strp",
"padding": "pdding",
"mandatory": true,
"attribute_id": "random.val",
"new_branch": true,
"timezone": "Local",
"blocker": true,
"layout": "",
"cost_shift_digits": 10,
"rounding_decimals": 1,
"mask_destinationd_id": "randomVal",
"mask_length": 10,
},
],
}
}`
eMap := map[string]any{
"custom_template": []map[string]any{
{
utils.TagCfg: "Tenant",
utils.TypeCfg: "*composed",
utils.PathCfg: "Tenant",
utils.FiltersCfg: []string{"val1", "val2"},
utils.ValueCfg: "cgrates.org",
utils.WidthCfg: 10,
utils.StripCfg: "strp",
utils.PaddingCfg: "pdding",
utils.MandatoryCfg: true,
utils.AttributeIDCfg: "random.val",
utils.NewBranchCfg: true,
utils.TimezoneCfg: "Local",
utils.BlockerCfg: true,
utils.LayoutCfg: "",
utils.CostShiftDigitsCfg: 10,
utils.RoundingDecimalsCfg: 1,
utils.MaskDestIDCfg: "randomVal",
utils.MaskLenCfg: 10,
},
},
}
if cgrCfg, err := NewCGRConfigFromJSONStringWithDefaults(cfgJSONStr); err != nil {
t.Error(err)
} else if rcv := cgrCfg.templates.AsMapInterface().(map[string][]map[string]any); !reflect.DeepEqual(eMap["custom_template"], rcv["custom_template"]) {
t.Errorf("Expected %+v \n, recieved %+v", utils.ToJSON(eMap["custom_template"]), utils.ToJSON(rcv["custom_template"]))
}
}
func TestFCTemplateAsMapInterface1(t *testing.T) {
cfgJSONStr := `{
"templates": {
"*err": [
{"tag": "SessionId", "path": "*rep.Session-Id", "type": "*variable",
"value": "~*req.Session-Id", "mandatory": true},
{"tag": "OriginHost", "path": "*rep.Origin-Host", "type": "*variable",
"value": "~*vars.OriginHost", "mandatory": true},
{"tag": "OriginRealm", "path": "*rep.Origin-Realm", "type": "*variable",
"value": "~*vars.OriginRealm", "mandatory": true},
],
"*asr": [
{"tag": "SessionId", "path": "*diamreq.Session-Id", "type": "*variable",
"value": "~*req.Session-Id", "mandatory": true},
{"tag": "OriginHost", "path": "*diamreq.Origin-Host", "type": "*variable",
"value": "~*req.Destination-Host", "mandatory": true},
{"tag": "OriginRealm", "path": "*diamreq.Origin-Realm", "type": "*variable",
"value": "~*req.Destination-Realm", "mandatory": true},
{"tag": "DestinationRealm", "path": "*diamreq.Destination-Realm", "type": "*variable",
"value": "~*req.Origin-Realm", "mandatory": true},
{"tag": "DestinationHost", "path": "*diamreq.Destination-Host", "type": "*variable",
"value": "~*req.Origin-Host", "mandatory": true},
{"tag": "AuthApplicationId", "path": "*diamreq.Auth-Application-Id", "type": "*variable",
"value": "~*vars.*appid", "mandatory": true},
],
}
}`
eMap := map[string]any{
utils.MetaErr: []map[string]any{
{utils.TagCfg: "SessionId", utils.PathCfg: "*rep.Session-Id", utils.TypeCfg: "*variable",
utils.ValueCfg: "~*req.Session-Id", utils.MandatoryCfg: true},
{utils.TagCfg: "OriginHost", utils.PathCfg: "*rep.Origin-Host", utils.TypeCfg: "*variable",
utils.ValueCfg: "~*vars.OriginHost", utils.MandatoryCfg: true},
{utils.TagCfg: "OriginRealm", utils.PathCfg: "*rep.Origin-Realm", utils.TypeCfg: "*variable",
utils.ValueCfg: "~*vars.OriginRealm", utils.MandatoryCfg: true},
},
utils.MetaASR: []map[string]any{
{utils.TagCfg: "SessionId", utils.PathCfg: "*diamreq.Session-Id", utils.TypeCfg: "*variable",
utils.ValueCfg: "~*req.Session-Id", utils.MandatoryCfg: true},
{utils.TagCfg: "OriginHost", utils.PathCfg: "*diamreq.Origin-Host", utils.TypeCfg: "*variable",
utils.ValueCfg: "~*req.Destination-Host", utils.MandatoryCfg: true},
{utils.TagCfg: "OriginRealm", utils.PathCfg: "*diamreq.Origin-Realm", utils.TypeCfg: "*variable",
utils.ValueCfg: "~*req.Destination-Realm", utils.MandatoryCfg: true},
{utils.TagCfg: "DestinationRealm", utils.PathCfg: "*diamreq.Destination-Realm", utils.TypeCfg: "*variable",
utils.ValueCfg: "~*req.Origin-Realm", utils.MandatoryCfg: true},
{utils.TagCfg: "DestinationHost", utils.PathCfg: "*diamreq.Destination-Host", utils.TypeCfg: "*variable",
utils.ValueCfg: "~*req.Origin-Host", utils.MandatoryCfg: true},
{utils.TagCfg: "AuthApplicationId", utils.PathCfg: "*diamreq.Auth-Application-Id", utils.TypeCfg: "*variable",
utils.ValueCfg: "~*vars.*appid", utils.MandatoryCfg: true},
},
}
if cgrCfg, err := NewCGRConfigFromJSONStringWithDefaults(cfgJSONStr); err != nil {
t.Error(err)
} else {
rcv := cgrCfg.templates.AsMapInterface().(map[string][]map[string]any)
if !reflect.DeepEqual(eMap[utils.MetaErr], rcv[utils.MetaErr]) {
t.Errorf("Expected %+v \n, recieved %+v", utils.ToJSON(eMap[utils.MetaErr]), utils.ToJSON(rcv[utils.MetaErr]))
} else if !reflect.DeepEqual(eMap[utils.MetaASR], rcv[utils.MetaASR]) {
t.Errorf("Expected %+v \n, recieved %+v", utils.ToJSON(eMap[utils.MetaASR]), utils.ToJSON(rcv[utils.MetaASR]))
}
}
}
func TestFCTemplatesClone(t *testing.T) {
smpl := FCTemplates{
utils.MetaErr: {{
Tag: "Tenant",
Type: "*composed",
Path: "Tenant",
Filters: []string{"Filter1", "Filter2"},
Value: utils.NewRSRParsersMustCompile("cgrates.org", utils.InfieldSep),
RoundingDecimals: utils.IntPointer(2),
}},
}
smpl[utils.MetaErr][0].ComputePath()
cloned := smpl.Clone()
if !reflect.DeepEqual(cloned, smpl) {
t.Errorf("expected: %s ,received: %s", utils.ToJSON(smpl), utils.ToJSON(cloned))
}
initialSmpl := FCTemplates{
utils.MetaErr: {{
Tag: "Tenant",
Type: "*composed",
Path: "Tenant",
Filters: []string{"Filter1", "Filter2"},
Value: utils.NewRSRParsersMustCompile("cgrates.org", utils.InfieldSep),
RoundingDecimals: utils.IntPointer(2),
}},
}
initialSmpl[utils.MetaErr][0].ComputePath()
smpl[utils.MetaErr] = nil
if !reflect.DeepEqual(cloned, initialSmpl) {
t.Errorf("expected: %s ,received: %s", utils.ToJSON(initialSmpl), utils.ToJSON(cloned))
}
}
func TestFcTemplatesEqual(t *testing.T) {
v1 := []*FCTemplate{
{
Tag: "TenantID",
Type: utils.MetaVariable,
Path: utils.Tenant,
Value: utils.RSRParsers{
{
Rules: "*req.0",
},
},
Filters: []string{"*string:~*req.Account:1001"},
Width: 2,
Strip: "strip",
Padding: "padding",
Mandatory: true,
AttributeID: "ATTR_PRF_1001",
NewBranch: true,
Timezone: "UTC",
Blocker: true,
Layout: "string",
CostShiftDigits: 2,
RoundingDecimals: utils.IntPointer(3),
MaskDestID: "MK_ID",
MaskLen: 2,
},
}
v2 := []*FCTemplate{
{
Tag: "TenantID",
Type: utils.MetaVariable,
Path: utils.Tenant,
Value: utils.RSRParsers{
{
Rules: "*req.0",
},
},
Filters: []string{"*string:~*req.Account:1001"},
Width: 2,
Strip: "strip",
Padding: "padding",
Mandatory: true,
AttributeID: "ATTR_PRF_1001",
NewBranch: true,
Timezone: "UTC",
Blocker: true,
Layout: "string",
CostShiftDigits: 2,
RoundingDecimals: utils.IntPointer(3),
MaskDestID: "MK_ID",
MaskLen: 2,
},
}
if !fcTemplatesEqual(v1, v2) {
t.Error("Templates should match")
}
v1[0].Tag = "TenantTag"
if fcTemplatesEqual(v1, v2) {
t.Error("Templates should not match")
}
newTemplate := &FCTemplate{
Tag: "TenantID",
Type: utils.MetaVariable,
Path: utils.Tenant,
Value: utils.RSRParsers{
{
Rules: "*req.0",
},
},
Filters: []string{"*string:~*req.Account:1001"},
Width: 2,
Strip: "strip",
Padding: "padding",
Mandatory: true,
AttributeID: "ATTR_PRF_1001",
NewBranch: true,
Timezone: "UTC",
Blocker: true,
Layout: "string",
CostShiftDigits: 2,
RoundingDecimals: utils.IntPointer(3),
MaskDestID: "MK_ID",
MaskLen: 2,
}
v2 = append(v2, newTemplate)
if fcTemplatesEqual(v1, v2) {
t.Error("Templates should not match")
}
}
func TestDiffFcTemplateJsonCfg(t *testing.T) {
var d []*FcTemplateJsonCfg
v1 := []*FCTemplate{
{
Tag: "TenantID2",
},
}
v2 := []*FCTemplate{
{
Tag: "TenantID",
Type: utils.MetaVariable,
Path: utils.Tenant,
Value: utils.RSRParsers{
{
Rules: "*req.0",
},
},
Filters: []string{"*string:~*req.Account:1001"},
Width: 2,
Strip: "strip",
Padding: "padding",
Mandatory: true,
AttributeID: "ATTR_PRF_1001",
NewBranch: true,
Timezone: "UTC",
Blocker: true,
Layout: "string",
CostShiftDigits: 2,
RoundingDecimals: utils.IntPointer(3),
MaskDestID: "MK_ID",
MaskLen: 2,
},
}
expected := []*FcTemplateJsonCfg{
{
Tag: utils.StringPointer("TenantID"),
Type: utils.StringPointer(utils.MetaVariable),
Path: utils.StringPointer(utils.Tenant),
Value: utils.StringPointer("*req.0"),
Filters: &[]string{"*string:~*req.Account:1001"},
Width: utils.IntPointer(2),
Strip: utils.StringPointer("strip"),
Padding: utils.StringPointer("padding"),
Mandatory: utils.BoolPointer(true),
Attribute_id: utils.StringPointer("ATTR_PRF_1001"),
New_branch: utils.BoolPointer(true),
Timezone: utils.StringPointer("UTC"),
Blocker: utils.BoolPointer(true),
Layout: utils.StringPointer("string"),
Cost_shift_digits: utils.IntPointer(2),
Rounding_decimals: utils.IntPointer(3),
Mask_destinationd_id: utils.StringPointer("MK_ID"),
Mask_length: utils.IntPointer(2),
},
}
rcv := diffFcTemplateJsonCfg(d, v1, v2)
if !reflect.DeepEqual(rcv, expected) {
t.Errorf("Expected %v \n but received \n %v", utils.ToJSON(expected), utils.ToJSON(rcv))
}
d = []*FcTemplateJsonCfg{
{
Tag: utils.StringPointer("Tag"),
},
}
v1 = v2
expected = []*FcTemplateJsonCfg{
{
Tag: utils.StringPointer("Tag"),
},
}
rcv = diffFcTemplateJsonCfg(d, v1, v2)
if !reflect.DeepEqual(rcv, expected) {
t.Errorf("Expected %v \n but received \n %v", utils.ToJSON(expected), utils.ToJSON(rcv))
}
}
func TestDiffFcTemplatesJsonCfg(t *testing.T) {
var d FcTemplatesJsonCfg
v1 := map[string][]*FCTemplate{}
v2 := FCTemplates{
"T1": {
{
Tag: "TenantID",
Type: utils.MetaVariable,
Path: utils.Tenant,
Value: utils.RSRParsers{
{
Rules: "*req.0",
},
},
Filters: []string{"*string:~*req.Account:1001"},
Width: 2,
Strip: "strip",
Padding: "padding",
Mandatory: true,
AttributeID: "ATTR_PRF_1001",
NewBranch: true,
Timezone: "UTC",
Blocker: true,
Layout: "string",
CostShiftDigits: 2,
RoundingDecimals: utils.IntPointer(3),
MaskDestID: "MK_ID",
MaskLen: 2,
},
},
}
expected := FcTemplatesJsonCfg{
"T1": {
{
Tag: utils.StringPointer("TenantID"),
Type: utils.StringPointer(utils.MetaVariable),
Path: utils.StringPointer(utils.Tenant),
Value: utils.StringPointer("*req.0"),
Filters: &[]string{"*string:~*req.Account:1001"},
Width: utils.IntPointer(2),
Strip: utils.StringPointer("strip"),
Padding: utils.StringPointer("padding"),
Mandatory: utils.BoolPointer(true),
Attribute_id: utils.StringPointer("ATTR_PRF_1001"),
New_branch: utils.BoolPointer(true),
Timezone: utils.StringPointer("UTC"),
Blocker: utils.BoolPointer(true),
Layout: utils.StringPointer("string"),
Cost_shift_digits: utils.IntPointer(2),
Rounding_decimals: utils.IntPointer(3),
Mask_destinationd_id: utils.StringPointer("MK_ID"),
Mask_length: utils.IntPointer(2),
},
},
}
rcv := diffFcTemplatesJsonCfg(d, v1, v2)
if !reflect.DeepEqual(rcv, expected) {
t.Errorf("Expected %v \n but received \n %v", utils.ToJSON(expected), utils.ToJSON(rcv))
}
v1 = v2
expected = FcTemplatesJsonCfg{
"T1": nil,
}
rcv = diffFcTemplatesJsonCfg(d, v1, v2)
if !reflect.DeepEqual(rcv, expected) {
t.Errorf("Expected %v \n but received \n %v", utils.ToJSON(expected), utils.ToJSON(rcv))
}
}
func TestFCTemplatecloneSection(t *testing.T) {
fctCfg := FCTemplates{
"T1": {
{
Tag: "TenantID",
Type: utils.MetaVariable,
Path: utils.Tenant,
Value: utils.RSRParsers{
{
Rules: "*req.0",
},
},
Filters: []string{"*string:~*req.Account:1001"},
Width: 2,
Strip: "strip",
Padding: "padding",
Mandatory: true,
AttributeID: "ATTR_PRF_1001",
NewBranch: true,
Timezone: "UTC",
Blocker: true,
Layout: "string",
CostShiftDigits: 2,
RoundingDecimals: utils.IntPointer(3),
MaskDestID: "MK_ID",
MaskLen: 2,
},
},
}
exp := FCTemplates{
"T1": {
{
Tag: "TenantID",
Type: utils.MetaVariable,
Path: utils.Tenant,
Value: utils.RSRParsers{
{
Rules: "*req.0",
},
},
Filters: []string{"*string:~*req.Account:1001"},
Width: 2,
Strip: "strip",
Padding: "padding",
Mandatory: true,
AttributeID: "ATTR_PRF_1001",
NewBranch: true,
Timezone: "UTC",
Blocker: true,
Layout: "string",
CostShiftDigits: 2,
RoundingDecimals: utils.IntPointer(3),
MaskDestID: "MK_ID",
MaskLen: 2,
},
},
}
rcv := fctCfg.CloneSection()
if !reflect.DeepEqual(rcv, exp) {
t.Errorf("Expected %v \n but received \n %v", utils.ToJSON(exp), utils.ToJSON(rcv))
}
}