diff --git a/engine/attributes_test.go b/engine/attributes_test.go index 54fedb706..daa3ed0f3 100644 --- a/engine/attributes_test.go +++ b/engine/attributes_test.go @@ -20,8 +20,11 @@ package engine import ( "bytes" + "encoding/json" "fmt" "log" + "net/http" + "net/http/httptest" "os" "reflect" "sort" @@ -1443,111 +1446,130 @@ func TestAttrSV1GetAttributeForEvent(t *testing.T) { } -// func TestAttributesV1ProcessEventSentryPeer(t *testing.T) { -// testServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { -// if r.Method == http.MethodPost { +func TestAttributesV1ProcessEventSentryPeer(t *testing.T) { + defer func() { + cfg2 := config.NewDefaultCGRConfig() + config.SetCgrConfig(cfg2) + }() + testServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.Method == http.MethodPost { -// if r.URL.EscapedPath() != "/oauth/token" { -// w.WriteHeader(http.StatusNotFound) -// return -// } -// contentType := r.Header.Get(utils.ContentType) -// if contentType != utils.JsonBody { -// w.WriteHeader(http.StatusBadRequest) -// return -// } -// var data map[string]string -// err := json.NewDecoder(r.Body).Decode(&data) -// if err != nil { -// w.WriteHeader(http.StatusBadRequest) -// return -// } -// response := struct { -// AccessToken string `json:"access_token"` -// }{ -// AccessToken: "302982309u2u30r23203", -// } -// w.WriteHeader(http.StatusOK) -// err = json.NewEncoder(w).Encode(response) -// if err != nil { -// http.Error(w, err.Error(), http.StatusInternalServerError) -// return -// } -// return -// } -// if r.Method != http.MethodGet { -// w.WriteHeader(http.StatusMethodNotAllowed) -// return -// } -// responses := map[string]struct { -// code int -// body []byte -// }{ -// "/api/phone-numbers/100": {code: http.StatusOK, body: []byte(`{"IP Address found"}`)}, -// } -// if val, has := responses[r.URL.EscapedPath()]; has { -// w.WriteHeader(val.code) -// if val.body != nil { -// w.Write(val.body) -// } -// return -// } -// })) -// cfg := config.NewDefaultCGRConfig() -// cfg.SentryPeerCfg().ClientID = "ererwffwssf" -// cfg.SentryPeerCfg().ClientSecret = "3354rf43f34sf" -// cfg.SentryPeerCfg().TokenUrl = testServer.URL + "/oauth/token" -// cfg.SentryPeerCfg().IpsUrl = testServer.URL + "/api/ip-addresses" -// cfg.SentryPeerCfg().NumbersUrl = testServer.URL + "/api/phone-numbers" -// dm := NewDataManager(NewInternalDB(nil, nil, true, cfg.DataDbCfg().Items), nil, nil) -// filterS := NewFilterS(cfg, nil, dm) + if r.URL.EscapedPath() != "/oauth/token" { + w.WriteHeader(http.StatusNotFound) + return + } + contentType := r.Header.Get(utils.ContentType) + if contentType != utils.JsonBody { + w.WriteHeader(http.StatusBadRequest) + return + } + var data map[string]string + err := json.NewDecoder(r.Body).Decode(&data) + if err != nil { + w.WriteHeader(http.StatusBadRequest) + return + } + response := struct { + AccessToken string `json:"access_token"` + }{ + AccessToken: "302982309u2u30r23203", + } + w.WriteHeader(http.StatusOK) + err = json.NewEncoder(w).Encode(response) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + return + } + if r.Method != http.MethodGet { + w.WriteHeader(http.StatusMethodNotAllowed) + return + } + responses := map[string]struct { + code int + body []byte + }{ + "/api/phone-numbers/453904509045": {code: http.StatusNotFound, body: []byte(`{"Number not found"}`)}, + "/api/phone-numbers/100": {code: http.StatusOK, body: []byte(`{"Number found"}`)}, + } + if val, has := responses[r.URL.EscapedPath()]; has { + w.WriteHeader(val.code) + if val.body != nil { + w.Write(val.body) + } + return + } + })) + cfg := config.NewDefaultCGRConfig() + cfg.SentryPeerCfg().ClientID = "ererwffwssf" + cfg.SentryPeerCfg().ClientSecret = "3354rf43f34sf" + cfg.SentryPeerCfg().TokenUrl = testServer.URL + "/oauth/token" + cfg.SentryPeerCfg().IpsUrl = testServer.URL + "/api/ip-addresses" + cfg.SentryPeerCfg().NumbersUrl = testServer.URL + "/api/phone-numbers" + cfg.AttributeSCfg().IndexedSelects = false + dm := NewDataManager(NewInternalDB(nil, nil, true, cfg.DataDbCfg().Items), nil, nil) + if err := dm.SetAttributeProfile(&AttributeProfile{ + Tenant: "cgrates.org", + ID: "ATTR_CHECK_DESTINATION", + Contexts: []string{}, + FilterIDs: []string{"*sentrypeer:~*req.Destination:*number"}, + Attributes: []*Attribute{ + { + Path: "*req.Destination", + Type: utils.MetaConstant, + Value: config.NewRSRParsersMustCompile("NUM", utils.InfieldSep), + }}, + Blocker: false, + Weight: 20}, true); err != nil { + t.Error(err) + } + filterS := NewFilterS(cfg, nil, dm) + alS := NewAttributeService(dm, filterS, cfg) + var rply AttrSProcessEventReply + expected := AttrSProcessEventReply{ + MatchedProfiles: []string{"cgrates.org:ATTR_CHECK_DESTINATION"}, + AlteredFields: []string{"*req.Destination"}, + CGREvent: &utils.CGREvent{ + Tenant: "cgrates.org", + Time: nil, + Event: map[string]any{ + utils.AccountField: "account_1001", + utils.Destination: "NUM", + }, + APIOpts: map[string]any{ + utils.OptsAttributesProcessRuns: 2, + }, + }, + blocker: false, + } + config.SetCgrConfig(cfg) + if err = alS.V1ProcessEvent(&utils.CGREvent{ + Tenant: "cgrates.org", + Event: map[string]any{ + utils.AccountField: "account_1001", + utils.Destination: "453904509045", + }, + APIOpts: map[string]any{ + utils.OptsAttributesProcessRuns: 2, + }, + }, &rply); err != nil { + t.Errorf("Expected <%+v>, received <%+v>", nil, err) + } else if sort.Strings(rply.AlteredFields); !reflect.DeepEqual(expected, rply) { + t.Errorf("Expected <%+v>, received <%+v>", utils.ToJSON(expected), utils.ToJSON(rply)) + } -// if err := dm.SetAttributeProfile(&AttributeProfile{ -// Tenant: "cgrates.org", -// ID: "ATTR_CHECK_DESTINATION", -// Contexts: []string{utils.MetaAny}, -// FilterIDs: []string{"*sentrypeer:~*req.Destination:*number"}, -// Attributes: []*Attribute{ -// { -// Path: "*req.Destination", -// Type: utils.MetaConstant, -// Value: config.NewRSRParsersMustCompile("BANNED_NUM", utils.InfieldSep), -// }}, -// Blocker: false, -// Weight: 20}, false); err != nil { -// t.Error(err) -// } + if err = alS.V1ProcessEvent(&utils.CGREvent{ + Tenant: "cgrates.org", + Event: map[string]any{ + utils.AccountField: "account_1001", + utils.Destination: "100", + }, + APIOpts: map[string]any{ + utils.OptsAttributesProcessRuns: 2, + }, + }, &rply); err == nil { + t.Errorf("Expected <%+v>, received <%+v>", err, nil) + } -// alS := NewAttributeService(dm, filterS, cfg) -// var rply AttrSProcessEventReply -// expected := AttrSProcessEventReply{ -// MatchedProfiles: []string{"cgrates.org:ATTR_CHECK_DESTINATION"}, -// AlteredFields: []string{"*req.Destination"}, -// CGREvent: &utils.CGREvent{ -// Tenant: "cgrates.org", -// Time: nil, -// Event: map[string]any{ -// utils.AccountField: "account_1001", -// utils.Destination: "BANNED_NUM", -// }, -// APIOpts: map[string]any{ -// utils.OptsAttributesProcessRuns: 2, -// }, -// }, -// blocker: false, -// } -// if err = alS.V1ProcessEvent(&utils.CGREvent{ -// Tenant: "cgrates.org", -// Event: map[string]any{ -// utils.AccountField: "account_1001", -// utils.Destination: "100", -// }, -// APIOpts: map[string]any{ -// utils.OptsAttributesProcessRuns: 2, -// }, -// }, &rply); err != nil { -// t.Errorf("Expected <%+v>, received <%+v>", nil, err) -// } else if sort.Strings(rply.AlteredFields); !reflect.DeepEqual(expected, rply) { -// t.Errorf("Expected <%+v>, received <%+v>", utils.ToJSON(expected), utils.ToJSON(rply)) -// } -// } +} diff --git a/engine/cdrs_test.go b/engine/cdrs_test.go index b770dd6f8..e938e10fa 100644 --- a/engine/cdrs_test.go +++ b/engine/cdrs_test.go @@ -2348,3 +2348,51 @@ func TestCDRSGetCDRs(t *testing.T) { t.Error(err) } } + +func TestV1RateCDRsSuccesful(t *testing.T) { + cfg := config.NewDefaultCGRConfig() + db := NewInternalDB(nil, nil, true, cfg.DataDbCfg().Items) + dm := NewDataManager(db, cfg.CacheCfg(), nil) + cdrS := &CDRServer{ + cgrCfg: cfg, + cdrDb: db, + dm: dm, + connMgr: nil, + } + cdr := &CDR{ + CGRID: utils.Sha1("dsafdsaf", time.Date(2023, 11, 7, 8, 42, 26, 0, time.UTC).String()), + OrderID: 123, + ToR: utils.MetaVoice, + OriginID: "dsafdsaf", + OriginHost: "192.168.1.1", + Source: utils.UnitTest, + RequestType: utils.MetaRated, + Tenant: "cgrates.org", + Category: "call", + Account: "1001", + Subject: "1002", + Destination: "+4986517174963", + SetupTime: time.Date(2023, 11, 7, 8, 42, 20, 0, time.UTC), + AnswerTime: time.Date(2023, 11, 7, 8, 42, 26, 0, time.UTC), + RunID: utils.MetaDefault, + Usage: 10 * time.Second, + Cost: 1.01, + } + if err := db.SetCDR(cdr, true); err != nil { + t.Error(err) + } + var reply string + arg := &ArgRateCDRs{ + Flags: []string{utils.MetaRerate}, + Tenant: "cgrates.org", + RPCCDRsFilter: utils.RPCCDRsFilter{ + Accounts: []string{"1001"}, + }, + APIOpts: map[string]any{}, + } + if err := cdrS.V1RateCDRs(arg, &reply); err != nil { + t.Error(err) + } else if reply != utils.OK { + t.Error("Expected reply to be ok") + } +} diff --git a/engine/filters_test.go b/engine/filters_test.go index 131cc81d8..ba188e2c8 100644 --- a/engine/filters_test.go +++ b/engine/filters_test.go @@ -2421,7 +2421,9 @@ func TestFilterLazyPassErr(t *testing.T) { func TestSentryPeer(t *testing.T) { token := "token27072023" + count := 0 testServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.Method == http.MethodPost { if r.URL.EscapedPath() != "/oauth/token" { @@ -2473,12 +2475,21 @@ func TestSentryPeer(t *testing.T) { "/api/ip-addresses/184.168.31.232": {code: http.StatusOK, body: []byte(`{"IP Address found"}`)}, "/api/phone-numbers/22663272712": {code: http.StatusNotFound, body: []byte(`Phone Number not found`)}, "/api/phone-numbers/90046322651795": {code: http.StatusOK, body: []byte(`{"Phone Number found`)}, + "/api/phone-numbers/1123452353245": {code: http.StatusUnauthorized, body: []byte(`{"Not Authorized`)}, } if val, has := responses[r.URL.EscapedPath()]; has { if r.Header.Get(utils.AuthorizationHdr) != utils.BearerAuth+" "+token { w.WriteHeader(http.StatusUnauthorized) return } + if count == 1 { + w.WriteHeader(http.StatusNotFound) + w.Write([]byte(`Phone number not found`)) + return + } + if val.code == http.StatusUnauthorized { + count++ + } w.WriteHeader(val.code) if val.body != nil { w.Write(val.body) @@ -2503,6 +2514,7 @@ func TestSentryPeer(t *testing.T) { "IP": "1.2.3.254", "Number": "22663272712", "BadNumber": "90046322651795", + "No": "1123452353245", }, } config.CgrConfig().SentryPeerCfg().ClientID = "ererwffwssf" @@ -2516,12 +2528,28 @@ func TestSentryPeer(t *testing.T) { } else if !pass { t.Error("Expected to pass") } + if val, has := Cache.Get(utils.MetaSentryPeer, utils.MetaToken); !has { + t.Error("Expected token to be set in the cahe") + } else if val.(string) != token { + t.Errorf("Expected +%v,Received +%v", token, val) + } + + if val, has := Cache.Get(utils.MetaSentryPeer, utils.ConcatenatedKey(utils.MetaIp, "1.2.3.254")); !has { + t.Error("value should had been set in cache") + } else if !val.(bool) { + t.Error("Expected item to be true") + } if pass, err := filterS.Pass("cgrates.org", []string{"*sentrypeer:~*req.BADIP:*ip"}, dp); err != nil { t.Error(err) } else if pass { t.Error("Expected to not pass") } + if val, has := Cache.Get(utils.MetaSentryPeer, utils.ConcatenatedKey(utils.MetaIp, "184.168.31.232")); !has { + t.Error("value should had been set in cache") + } else if val.(bool) { + t.Error("Expected item to be false") + } if pass, err := filterS.Pass("cgrates.org", []string{"*sentrypeer:~*req.Number:*number"}, dp); err != nil { t.Error(err) @@ -2529,10 +2557,33 @@ func TestSentryPeer(t *testing.T) { t.Error("Expected to pass") } + if val, has := Cache.Get(utils.MetaSentryPeer, utils.ConcatenatedKey(utils.MetaNumber, "22663272712")); !has { + t.Error("value should had been set in cache") + } else if !val.(bool) { + t.Error("Expected item to be true") + } + if pass, err := filterS.Pass("cgrates.org", []string{"*sentrypeer:~*req.BadNumber:*number"}, dp); err != nil { t.Error(err) } else if pass { t.Error("Expected to not pass") } + if val, has := Cache.Get(utils.MetaSentryPeer, utils.ConcatenatedKey(utils.MetaNumber, "90046322651795")); !has { + t.Error("value should had been set in cache") + } else if val.(bool) { + t.Error("Expected item to be false") + } + + if pass, err := filterS.Pass("cgrates.org", []string{"*sentrypeer:~*req.No:*number"}, dp); err != nil { + t.Error(err) + } else if !pass { + t.Error("Expected to pass") + } + + if val, has := Cache.Get(utils.MetaSentryPeer, utils.ConcatenatedKey(utils.MetaNumber, "1123452353245")); !has { + t.Error("value should had been set in cache") + } else if !val.(bool) { + t.Error("Expected item to be true") + } }