/* 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 */ package config import ( "path" "reflect" "strings" "testing" "github.com/antchfx/xmlquery" "github.com/cgrates/cgrates/utils" ) var cdrXMLBroadsoft = ` 0002183384 CGRateSaabb 20160419210000.104 1+020000 Start 0002183385 CGRateSaabb 20160419210005.247 1+020000 MBC Normal 1001 2001 Network 1001 Public +4986517174963 20160419210005.247 1+020000 25160047719:0 Yes 20160419210006.813 20160419210020.296 016 y local 1001@cgrates.org Yes Yes CGR_GROUP CGR_GROUP/CGR_GROUP_TRUNK30 Normal 1001@cgrates.org Primary Device 31.882 gw04.cgrates.org 74122796919420162305@172.16.1.2 PCMA/8000 172.16.1.4 BW2300052501904161738474465@172.16.1.10 31.882 OmniPCX Enterprise R11.0.1 k1.520.22.b 0002183386 CGRateSaabb 20160419210006.909 1+020000 MBC Normal 1002 2001 Network +4986517174964 Public 1002 20160419210006.909 1+020000 27280048121:0 Yes 20160419210007.037 20160419210030.322 016 y local 314028947650@cgrates.org Yes Yes CGR_GROUP CGR_GROUP/CGR_GROUP_TRUNK65 Normal 31403456100@cgrates.org Primary Device 26.244 gw01.cgrates.org 108352493719420162306@172.31.250.150 PCMA/8000 172.16.1.4 2345300069121904161716512907@172.16.1.10 26.244 Altitude vBox 0002183486 CGRateSaabb 20160419211500.104 1+020000 End ` func TestXMLElementText(t *testing.T) { doc, err := xmlquery.Parse(strings.NewReader(cdrXMLBroadsoft)) if err != nil { t.Error(err) } cdrs := xmlquery.Find(doc, path.Join("/broadWorksCDR/cdrData/")) cdrWithoutUserNr := cdrs[0] if _, err := ElementText(cdrWithoutUserNr, "basicModule/userNumber"); err != utils.ErrNotFound { t.Error(err) } cdrWithUser := cdrs[1] if val, err := ElementText(cdrWithUser, "basicModule/userNumber"); err != nil { t.Error(err) } else if val != "1001" { t.Errorf("Expecting: 1001, received: %s", val) } if val, err := ElementText(cdrWithUser, "centrexModule/locationList/locationInformation/locationType"); err != nil { t.Error(err) } else if val != "Primary Device" { t.Errorf("Expecting: , received: <%s>", val) } } var xmlContent = ` Metaswitch CFS 1510225200002 National Orig 19 480 No answer 223007622 +27110493421 +27110493421 +27110493421 Ro_test 0gQAAC8WAAACBAAALxYAAD57SAEV7ekv/OSKkO7qmD82OmbfHO+Z7wIZJkXdCv8z@10.170.248.200 1 0 8824071D@10.170.248.140 19 480 0763371551 +270763371551 0763371551 110493421 110493421 False NetworkDefault 0 Speech 13442698e525ad2c21251f76479ab2b4 voice.lab.liquidtelecom.net 1510225513055 1510225513304 1510225514836 1510225516981 1510225516981 1510225516981 Premium Orig 16 No error 223007623 +27110493421 +27110493421 +27110493421 Ro_test 0gQAAC8WAAACBAAALxYAAPkyWDO29Do1SyxNi5UV71mJYEIEkfNa9wCFCCjY2asU@10.170.248.200 1 0 8E450FA1@10.170.248.140 0843073451 +270843073451 0843073451 110493421 110493421 False NetworkDefault 0 Speech 46d7974398c2671016afccc3f2c428c7 voice.lab.liquidtelecom.net 1510225531933 1510225532183 1510225534973 1510225539364 1510225593101 1510225593101 1510225593101 International Orig 16 No error 223007624 +27110493421 +27110493421 +27110493421 Ro_test 0gQAAC8WAAACBAAALxYAAJrUscTicyU5GtjPyQnpAeuNmz9p/bdOoR/Mk9RXciOI@10.170.248.200 1 0 BC8B2801@10.170.248.140 263772822306 +263772822306 263772822306 110493421 110493421 False NetworkDefault 0 Speech 750b8b73e41ba7b59b21240758522268 voice.lab.liquidtelecom.net 1510225865894 1510225866144 1510225866756 1510225876243 1510225916144 1510225916144 1510225916144 1510227591467 3 0 0 ` func TestXMLElementText3(t *testing.T) { doc, err := xmlquery.Parse(strings.NewReader(xmlContent)) if err != nil { t.Error(err) } hPath2 := utils.ParseHierarchyPath("File.CDRs.Call", "") cdrs := xmlquery.Find(doc, hPath2.AsString("/", true)) if len(cdrs) != 3 { t.Errorf("Expecting: 3, received: %+v", len(cdrs)) } if _, err := ElementText(cdrs[0], "SignalingInfo/PChargingVector/test"); err != utils.ErrNotFound { t.Error(err) } if val, err := ElementText(cdrs[1], "SignalingInfo/PChargingVector/icidvalue"); err != nil { t.Error(err) } else if val != "46d7974398c2671016afccc3f2c428c7" { t.Errorf("Expecting: 46d7974398c2671016afccc3f2c428c7, received: %s", val) } } var xmlMultipleIndex = ` 2005-08-26T14:16:42 2005-08-26T14:16:56 2005-08-26T14:17:34 My Call Reference 386 sampleusername 1 Conecto LLC US$0.21 yes no US$0.13 44 +441624828505 Isle of Man 38 US$0.0200 US$0.0140 US$0.0130 US$0.0082 +44 7624 494075 Isle of Man 37 US$0.2700 US$0.1890 US$0.1880 US$0.1159 ` func TestXMLIndexes(t *testing.T) { doc, err := xmlquery.Parse(strings.NewReader(xmlMultipleIndex)) if err != nil { t.Error(err) } dP := NewXMLProvider(doc, utils.HierarchyPath([]string{})) if data, err := dP.FieldAsString([]string{"complete-success-notification", "userid"}); err != nil { t.Error(err) } else if data != "386" { t.Errorf("expecting: 386, received: <%s>", data) } if data, err := dP.FieldAsString([]string{"complete-success-notification", "username"}); err != nil { t.Error(err) } else if data != "sampleusername" { t.Errorf("expecting: sampleusername, received: <%s>", data) } if data, err := dP.FieldAsString([]string{"complete-success-notification", "callleg", "seconds"}); err != nil { t.Error(err) } else if data != "38" { t.Errorf("expecting: 38, received: <%s>", data) } if data, err := dP.FieldAsString([]string{"complete-success-notification", "callleg[1]", "seconds"}); err != nil { t.Error(err) } else if data != "37" { t.Errorf("expecting: 37, received: <%s>", data) } if data, err := dP.FieldAsString([]string{"complete-success-notification", "callleg[@calllegid='222147']", "seconds"}); err != nil { t.Error(err) } else if data != "37" { t.Errorf("expecting: 37, received: <%s>", data) } } func TestFieldAsStringXMLEmptyPath(t *testing.T) { doc, err := xmlquery.Parse(strings.NewReader(xmlMultipleIndex)) if err != nil { t.Error(err) } dP := &XMLProvider{ req: doc, cdrPath: []string{}, cache: utils.MapStorage{}, } if _, err := dP.FieldAsString(dP.cdrPath); err == nil || err != utils.ErrNotFound { t.Errorf("Expected %+q, received %+q", utils.ErrNotFound, err) } } func TestStringXML(t *testing.T) { hP := utils.HierarchyPath{"complete-success-notification", "agentid"} doc, err := xmlquery.Parse(strings.NewReader(xmlMultipleIndex)) if err != nil { t.Fatal(err) } xmlElmts, err := xmlquery.QueryAll(doc, hP.AsString("/", true)) if err != nil { t.Fatal(err) } dP := NewXMLProvider(xmlElmts[0], hP) _, err = dP.FieldAsInterface([]string{"complete-success-notification", "agentid"}) if err != nil { t.Fatal(err) } expected := "{\"complete-success-notification\":{\"agentid\":\"44\"}}" if received := dP.String(); received != expected { t.Errorf("Expected %q, received %q", expected, received) } } func TestFieldAsInterfaceCache(t *testing.T) { doc, err := xmlquery.Parse(strings.NewReader(xmlMultipleIndex)) if err != nil { t.Error(err) } dP := &XMLProvider{ req: doc, cdrPath: []string{}, cache: utils.MapStorage{ "complete-success-notification": "randomValue", }, } expected := "randomValue" if received, err := dP.FieldAsString([]string{"complete-success-notification"}); err != nil { t.Error(err) } else if !reflect.DeepEqual(received, expected) { t.Errorf("Expected %+v, received %+v", expected, received) } } func TestFieldAsInterfaceInvalidSyntax(t *testing.T) { doc, err := xmlquery.Parse(strings.NewReader(xmlMultipleIndex)) if err != nil { t.Error(err) } dP := NewXMLProvider(doc, utils.HierarchyPath([]string{})) expected := "strconv.Atoi: parsing \"09]\": invalid syntax" if _, err := dP.FieldAsString([]string{"complete-success-notification[09]]"}); err == nil || err.Error() != expected { t.Errorf("Expected %+q, received %+q", expected, err) } } func TestFieldAsInterfaceInvalidSyntax1(t *testing.T) { doc, err := xmlquery.Parse(strings.NewReader(xmlMultipleIndex)) if err != nil { t.Error(err) } dP := NewXMLProvider(doc, utils.HierarchyPath([]string{})) expected := "filter rule <[0> needs to end in ]" if _, err := dP.FieldAsString([]string{"complete-success-notification[0"}); err == nil || err.Error() != expected { t.Errorf("Expected %+q, received %+q", expected, err) } } func TestElementTextErr(t *testing.T) { _, err := ElementText(&xmlquery.Node{}, utils.EmptyString) exp := "expr expression is nil" if err == nil || err.Error() != exp { t.Errorf("Expected: %v,received: %v", exp, err) } }